aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2009-12-22 17:20:51 +0000
committerVincent Hennebert <vhennebert@apache.org>2009-12-22 17:20:51 +0000
commit37b744039a701d5aafd44997a195c696261d3fea (patch)
tree504f0326b76734cf106ece1b67cf2fca8fd48ac3
parenta0f281543e947da203e9cfd5cb3559e32912beb4 (diff)
downloadxmlgraphics-fop-37b744039a701d5aafd44997a195c696261d3fea.tar.gz
xmlgraphics-fop-37b744039a701d5aafd44997a195c696261d3fea.zip
Bugzilla #48071: made the MinOptMax class immutable. Also, lots of clean ups and minor refactorings.
Patch submitted by Alexander Kiel. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@893238 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/area/Area.java10
-rw-r--r--src/java/org/apache/fop/fo/properties/LengthRangeProperty.java17
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java74
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java10
-rw-r--r--src/java/org/apache/fop/layoutmgr/Adjustment.java73
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java176
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java16
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java144
-rw-r--r--src/java/org/apache/fop/layoutmgr/BorderOrPaddingElement.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/ElementListUtils.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java46
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthBox.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthElement.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthGlue.java56
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutContext.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/LeafPosition.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java115
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreaker.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/SpaceElement.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/SpaceResolver.java95
-rw-r--r--src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java71
-rw-r--r--src/java/org/apache/fop/layoutmgr/TraitSetter.java94
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java53
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java21
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java29
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java20
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java57
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java31
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java61
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java1223
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java10
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/ActiveCell.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java19
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java19
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableStepper.java10
-rw-r--r--src/java/org/apache/fop/traits/MinOptMax.java357
-rw-r--r--src/java/org/apache/fop/traits/SpaceVal.java60
-rw-r--r--test/java/org/apache/fop/StandardTestSuite.java5
-rw-r--r--test/java/org/apache/fop/traits/MinOptMaxTest.java199
52 files changed, 1746 insertions, 1521 deletions
diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java
index 87ba2146a..ddf2f5198 100644
--- a/src/java/org/apache/fop/area/Area.java
+++ b/src/java/org/apache/fop/area/Area.java
@@ -119,7 +119,7 @@ public class Area extends AreaTreeObject implements Serializable {
public static final int CLASS_MAX = CLASS_SIDE_FLOAT + 1;
private int areaClass = CLASS_NORMAL;
-
+
/** the area's inline-progression-dimension */
protected int ipd;
@@ -174,18 +174,18 @@ public class Area extends AreaTreeObject implements Serializable {
* @see <a href="http://www.w3.org/TR/xsl/#inline-progression-dimension">ipd</a>
*/
public int getIPD() {
- return this.ipd;
+ return ipd;
}
/**
* Set the block progression dimension of the content rectangle
* for this area.
*
- * @param b the new block progression dimension
+ * @param bpd the new block progression dimension
* @see <a href="http://www.w3.org/TR/xsl/#block-progression-dimension">bpd</a>
*/
- public void setBPD(int b) {
- bpd = b;
+ public void setBPD(int bpd) {
+ this.bpd = bpd;
}
/**
diff --git a/src/java/org/apache/fop/fo/properties/LengthRangeProperty.java b/src/java/org/apache/fop/fo/properties/LengthRangeProperty.java
index 3161fc517..d8e8ee272 100644
--- a/src/java/org/apache/fop/fo/properties/LengthRangeProperty.java
+++ b/src/java/org/apache/fop/fo/properties/LengthRangeProperty.java
@@ -25,6 +25,7 @@ import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.traits.MinOptMax;
/**
* Superclass for properties that contain LengthRange values
@@ -40,6 +41,22 @@ public class LengthRangeProperty extends Property implements CompoundDatatype {
private boolean consistent = false;
/**
+ * Converts this <code>LengthRangeProperty</code> to a <code>MinOptMax</code>.
+ *
+ * @param context Percentage evaluation context
+ * @return the requested MinOptMax instance
+ */
+ public MinOptMax toMinOptMax(PercentBaseContext context) {
+ int min = getMinimum(context).isAuto() ? 0
+ : getMinimum(context).getLength().getValue(context);
+ int opt = getOptimum(context).isAuto() ? min
+ : getOptimum(context).getLength().getValue(context);
+ int max = getMaximum(context).isAuto() ? Integer.MAX_VALUE
+ : getMaximum(context).getLength().getValue(context);
+ return MinOptMax.getInstance(min, opt, max);
+ }
+
+ /**
* Inner class for a Maker for LengthProperty objects
*/
public static class Maker extends CompoundPropertyMaker {
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index a58f5523b..db0edb42c 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -201,7 +201,7 @@ public abstract class AbstractBreaker {
protected int alignment;
private int alignmentLast;
- protected MinOptMax footnoteSeparatorLength = new MinOptMax(0);
+ protected MinOptMax footnoteSeparatorLength = MinOptMax.ZERO;
protected abstract int getCurrentDisplayAlign();
protected abstract boolean hasMoreContent();
@@ -307,7 +307,7 @@ public abstract class AbstractBreaker {
*/
public void doLayout(int flowBPD, boolean autoHeight) {
LayoutContext childLC = createLayoutContext();
- childLC.setStackLimitBP(new MinOptMax(flowBPD));
+ childLC.setStackLimitBP(MinOptMax.getInstance(flowBPD));
if (getCurrentDisplayAlign() == Constants.EN_X_FILL) {
//EN_X_FILL is non-standard (by LF)
@@ -613,7 +613,7 @@ public abstract class AbstractBreaker {
int averageLineLength = optimizeLineLength(effectiveList,
startElementIndex, endElementIndex);
if (averageLineLength != 0) {
- childLC.setStackLimitBP(new MinOptMax(averageLineLength));
+ childLC.setStackLimitBP(MinOptMax.getInstance(averageLineLength));
}
}
/* *** *** non-standard extension *** *** */
@@ -762,7 +762,8 @@ public abstract class AbstractBreaker {
* @param endElementIndex index of the element ending the range
* @return the average line length, 0 if there's no content
*/
- private int optimizeLineLength(KnuthSequence effectiveList, int startElementIndex, int endElementIndex) {
+ private int optimizeLineLength(KnuthSequence effectiveList, int startElementIndex,
+ int endElementIndex) {
ListIterator effectiveListIterator;
// optimize line length
int boxCount = 0;
@@ -783,9 +784,9 @@ public abstract class AbstractBreaker {
accumulatedLineLength += ((KnuthBlockBox) tempEl)
.getBPD();
}
- if (blockBox.getIPDRange().min > greatestMinimumLength) {
+ if (blockBox.getIPDRange().getMin() > greatestMinimumLength) {
greatestMinimumLength = blockBox
- .getIPDRange().min;
+ .getIPDRange().getMin();
}
}
}
@@ -808,7 +809,8 @@ public abstract class AbstractBreaker {
* @param availableBPD the available BPD
* @return the effective list
*/
- private BlockSequence justifyBoxes(BlockSequence blockList, PageBreakingAlgorithm alg, int availableBPD) {
+ private BlockSequence justifyBoxes(BlockSequence blockList, PageBreakingAlgorithm alg,
+ int availableBPD) {
int iOptPageNumber;
alg.setConstantLineWidth(availableBPD);
iOptPageNumber = alg.findBreakingPoints(blockList, /*availableBPD,*/
@@ -857,8 +859,8 @@ public abstract class AbstractBreaker {
// scan the sub-sequence representing a page,
// collecting information about potential adjustments
- MinOptMax lineNumberMaxAdjustment = new MinOptMax(0);
- MinOptMax spaceMaxAdjustment = new MinOptMax(0);
+ MinOptMax lineNumberMaxAdjustment = MinOptMax.ZERO;
+ MinOptMax spaceMaxAdjustment = MinOptMax.ZERO;
double spaceAdjustmentRatio = 0.0;
LinkedList blockSpacesList = new LinkedList();
LinkedList unconfirmedList = new LinkedList();
@@ -872,30 +874,23 @@ public abstract class AbstractBreaker {
// glue elements are used to represent adjustable
// lines
// and adjustable spaces between blocks
- switch (((KnuthGlue) thisElement)
- .getAdjustmentClass()) {
- case BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT:
- // fall through
- case BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT:
+ Adjustment adjustment = ((KnuthGlue) thisElement).getAdjustmentClass();
+ if (adjustment.equals(Adjustment.SPACE_BEFORE_ADJUSTMENT)
+ || adjustment.equals(Adjustment.SPACE_AFTER_ADJUSTMENT)) {
// potential space adjustment
// glue items before the first box or after the
// last one
// must be ignored
unconfirmedList.add(thisElement);
- break;
- case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT:
+ } else if (adjustment.equals(Adjustment.LINE_NUMBER_ADJUSTMENT)) {
// potential line number adjustment
- lineNumberMaxAdjustment.max += ((KnuthGlue) thisElement)
- .getStretch();
- lineNumberMaxAdjustment.min -= ((KnuthGlue) thisElement)
- .getShrink();
+ lineNumberMaxAdjustment
+ = lineNumberMaxAdjustment.plusMax(thisElement.getStretch());
+ lineNumberMaxAdjustment
+ = lineNumberMaxAdjustment.minusMin(thisElement.getShrink());
adjustableLinesList.add(thisElement);
- break;
- case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT:
+ } else if (adjustment.equals(Adjustment.LINE_HEIGHT_ADJUSTMENT)) {
// potential line height adjustment
- break;
- default:
- // nothing
}
} else if (thisElement.isBox()) {
if (!bBoxSeen) {
@@ -909,10 +904,8 @@ public abstract class AbstractBreaker {
// blockSpaceList
KnuthGlue blockSpace = (KnuthGlue) unconfirmedList
.removeFirst();
- spaceMaxAdjustment.max += ((KnuthGlue) blockSpace)
- .getStretch();
- spaceMaxAdjustment.min -= ((KnuthGlue) blockSpace)
- .getShrink();
+ spaceMaxAdjustment = spaceMaxAdjustment.plusMax(blockSpace.getStretch());
+ spaceMaxAdjustment = spaceMaxAdjustment.minusMin(blockSpace.getShrink());
blockSpacesList.add(blockSpace);
}
}
@@ -931,16 +924,19 @@ public abstract class AbstractBreaker {
}
if (thisBreak.bpdAdjust != 0
- && (thisBreak.difference > 0 && thisBreak.difference <= spaceMaxAdjustment.max)
- || (thisBreak.difference < 0 && thisBreak.difference >= spaceMaxAdjustment.min)) {
+ && (thisBreak.difference > 0 && thisBreak.difference <= spaceMaxAdjustment
+ .getMax())
+ || (thisBreak.difference < 0 && thisBreak.difference >= spaceMaxAdjustment
+ .getMin())) {
// modify only the spaces between blocks
- spaceAdjustmentRatio = ((double) thisBreak.difference / (thisBreak.difference > 0 ? spaceMaxAdjustment.max
- : spaceMaxAdjustment.min));
+ spaceAdjustmentRatio = ((double) thisBreak.difference / (thisBreak.difference > 0
+ ? spaceMaxAdjustment.getMax()
+ : spaceMaxAdjustment.getMin()));
adjustedDiff += adjustBlockSpaces(
blockSpacesList,
thisBreak.difference,
- (thisBreak.difference > 0 ? spaceMaxAdjustment.max
- : -spaceMaxAdjustment.min));
+ (thisBreak.difference > 0 ? spaceMaxAdjustment.getMax()
+ : -spaceMaxAdjustment.getMin()));
log.debug("single space: "
+ (adjustedDiff == thisBreak.difference
|| thisBreak.bpdAdjust == 0 ? "ok"
@@ -949,13 +945,13 @@ public abstract class AbstractBreaker {
adjustedDiff += adjustLineNumbers(
adjustableLinesList,
thisBreak.difference,
- (thisBreak.difference > 0 ? lineNumberMaxAdjustment.max
- : -lineNumberMaxAdjustment.min));
+ (thisBreak.difference > 0 ? lineNumberMaxAdjustment.getMax()
+ : -lineNumberMaxAdjustment.getMin()));
adjustedDiff += adjustBlockSpaces(
blockSpacesList,
thisBreak.difference - adjustedDiff,
- ((thisBreak.difference - adjustedDiff) > 0 ? spaceMaxAdjustment.max
- : -spaceMaxAdjustment.min));
+ ((thisBreak.difference - adjustedDiff) > 0 ? spaceMaxAdjustment.getMax()
+ : -spaceMaxAdjustment.getMin()));
log.debug("lines and space: "
+ (adjustedDiff == thisBreak.difference
|| thisBreak.bpdAdjust == 0 ? "ok"
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
index e6a5bea5e..1f91cef1a 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
@@ -48,7 +48,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
private static Log log = LogFactory.getLog(AbstractLayoutManager.class);
/** Parent LayoutManager for this LayoutManager */
- protected LayoutManager parentLM;
+ protected LayoutManager parentLayoutManager;
/** List of child LayoutManagers */
protected List childLMs;
/** Iterator for child LayoutManagers */
@@ -91,12 +91,12 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
/** {@inheritDoc} */
public void setParent(LayoutManager lm) {
- this.parentLM = lm;
+ this.parentLayoutManager = lm;
}
/** {@inheritDoc} */
public LayoutManager getParent() {
- return this.parentLM;
+ return this.parentLayoutManager;
}
/** {@inheritDoc} */
@@ -230,7 +230,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
/** {@inheritDoc} */
public PageSequenceLayoutManager getPSLM() {
- return parentLM.getPSLM();
+ return parentLayoutManager.getPSLM();
}
/**
@@ -442,7 +442,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
* LM is a descendant of the FlowLM. For static-content
* the FO may still be needed on following pages.
*/
- LayoutManager lm = this.parentLM;
+ LayoutManager lm = this.parentLayoutManager;
while (!(lm instanceof FlowLayoutManager
|| lm instanceof PageSequenceLayoutManager)) {
lm = lm.getParent();
diff --git a/src/java/org/apache/fop/layoutmgr/Adjustment.java b/src/java/org/apache/fop/layoutmgr/Adjustment.java
new file mode 100644
index 000000000..0a96fb2c1
--- /dev/null
+++ b/src/java/org/apache/fop/layoutmgr/Adjustment.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+/**
+ * @see KnuthGlue
+ * @see "http://www.leverkruid.eu/GKPLinebreaking/elements.html"
+ */
+public final class Adjustment {
+
+ /**
+ * Adjustment class: no adjustment.
+ */
+ public static final Adjustment NO_ADJUSTMENT = new Adjustment("none");
+
+ /**
+ * Adjustment class: adjustment for space-before.
+ */
+ public static final Adjustment SPACE_BEFORE_ADJUSTMENT = new Adjustment("space-before");
+
+ /**
+ * Adjustment class: adjustment for space-after.
+ */
+ public static final Adjustment SPACE_AFTER_ADJUSTMENT = new Adjustment("space-after");
+
+ /**
+ * Adjustment class: adjustment for number of lines.
+ */
+ public static final Adjustment LINE_NUMBER_ADJUSTMENT = new Adjustment("line-number");
+
+ /**
+ * Adjustment class: adjustment for line height.
+ */
+ public static final Adjustment LINE_HEIGHT_ADJUSTMENT = new Adjustment("line-height");
+
+ private final String name;
+
+ private Adjustment(String name) {
+ this.name = name;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ /** {@inheritDoc} */
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return name;
+ }
+}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index 3378d86d7..5ca2b567f 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -107,8 +107,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
startIndent = getBlockContainerFO().getCommonMarginBlock().startIndent.getValue(this);
endIndent = getBlockContainerFO().getCommonMarginBlock().endIndent.getValue(this);
- boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
- if (rotated) {
+ if (blockProgressionDirectionChanges()) {
height = getBlockContainerFO().getInlineProgressionDimension()
.getOptimum(this).getLength();
width = getBlockContainerFO().getBlockProgressionDimension()
@@ -156,10 +155,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW);
}
- private int getSpaceBefore() {
- return foBlockSpaceBefore.opt;
- }
-
private int getBPIndents() {
int indents = 0;
/* TODO This is wrong isn't it?
@@ -200,7 +195,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
autoHeight = false;
//boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
- int maxbpd = context.getStackLimitBP().opt;
+ int maxbpd = context.getStackLimitBP().getOpt();
int allocBPD;
if (height.getEnum() == EN_AUTO
|| (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
@@ -246,7 +241,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
getBlockContainerFO().getLocator());
}
- MinOptMax stackLimit = new MinOptMax(relDims.bpd);
+ MinOptMax stackLimit = MinOptMax.getInstance(relDims.bpd);
List returnedList;
List contentList = new LinkedList();
@@ -279,7 +274,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
LayoutContext childLC = new LayoutContext(0);
childLC.copyPendingMarksFrom(context);
// curLM is a ?
- childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+ childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(relDims.ipd);
childLC.setWritingMode(getBlockContainerFO().getWritingMode());
if (curLM == this.childLMs.get(0)) {
@@ -349,41 +344,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
wrapPositionElements(contentList, returnList);
} else {
- MinOptMax range = new MinOptMax(relDims.ipd);
- BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
- breaker.doLayout(relDims.bpd, autoHeight);
- boolean contentOverflows = breaker.isOverflow();
- if (autoHeight) {
- //Update content BPD now that it is known
- int newHeight = breaker.deferredAlg.totalWidth;
- boolean switchedProgressionDirection
- = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
- if (switchedProgressionDirection) {
- setContentAreaIPD(newHeight);
- } else {
- vpContentBPD = newHeight;
- }
- updateRelDims(contentRectOffsetX, contentRectOffsetY, false);
- }
-
- Position bcPosition = new BlockContainerPosition(this, breaker);
- returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false));
- //TODO Handle min/opt/max for block-progression-dimension
- /* These two elements will be used to add stretchability to the above box
- returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
- false, returnPosition, false));
- returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
- LINE_NUMBER_ADJUSTMENT, returnPosition, false));
- */
-
- if (contentOverflows) {
- BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
- getBlockContainerFO().getUserAgent().getEventBroadcaster());
- boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
- eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
- breaker.getOverflowAmount(), needClip(), canRecover,
- getBlockContainerFO().getLocator());
- }
+ returnList.add(refactoredBecauseOfDuplicateCode(contentRectOffsetX,
+ contentRectOffsetY));
}
addKnuthElementsForBorderPaddingAfter(returnList, true);
addKnuthElementsForSpaceAfter(returnList, alignment);
@@ -398,6 +360,49 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
return returnList;
}
+ private KnuthBox refactoredBecauseOfDuplicateCode(double contentRectOffsetX,
+ double contentRectOffsetY) {
+
+ MinOptMax range = MinOptMax.getInstance(relDims.ipd);
+ BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
+ breaker.doLayout(relDims.bpd, autoHeight);
+ boolean contentOverflows = breaker.isOverflow();
+ if (autoHeight) {
+ //Update content BPD now that it is known
+ int newHeight = breaker.deferredAlg.totalWidth;
+ if (blockProgressionDirectionChanges()) {
+ setContentAreaIPD(newHeight);
+ } else {
+ vpContentBPD = newHeight;
+ }
+ updateRelDims(contentRectOffsetX, contentRectOffsetY, false);
+ }
+
+ Position bcPosition = new BlockContainerPosition(this, breaker);
+ KnuthBox knuthBox = new KnuthBox(vpContentBPD, notifyPos(bcPosition), false);
+ //TODO Handle min/opt/max for block-progression-dimension
+ /* These two elements will be used to add stretchability to the above box
+ returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
+ false, returnPosition, false));
+ returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
+ LINE_NUMBER_ADJUSTMENT, returnPosition, false));
+ */
+
+ if (contentOverflows) {
+ BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
+ getBlockContainerFO().getUserAgent().getEventBroadcaster());
+ boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
+ eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
+ breaker.getOverflowAmount(), needClip(), canRecover,
+ getBlockContainerFO().getLocator());
+ }
+ return knuthBox;
+ }
+
+ private boolean blockProgressionDirectionChanges() {
+ return getBlockContainerFO().getReferenceOrientation() % 180 != 0;
+ }
+
/** {@inheritDoc} */
public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
Position restartPosition, LayoutManager restartAtLM) {
@@ -408,7 +413,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
autoHeight = false;
//boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
- int maxbpd = context.getStackLimitBP().opt;
+ int maxbpd = context.getStackLimitBP().getOpt();
int allocBPD;
if (height.getEnum() == EN_AUTO
|| (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
@@ -454,7 +459,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
getBlockContainerFO().getLocator());
}
- MinOptMax stackLimit = new MinOptMax(relDims.bpd);
+ MinOptMax stackLimit = MinOptMax.getInstance(relDims.bpd);
List returnedList;
List contentList = new LinkedList();
@@ -492,7 +497,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
setCurrentChildLM(curLM);
childLC.copyPendingMarksFrom(context);
- childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+ childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(relDims.ipd);
childLC.setWritingMode(getBlockContainerFO().getWritingMode());
if (curLM == this.childLMs.get(0)) {
@@ -507,7 +512,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
setCurrentChildLM(curLM);
childLC.copyPendingMarksFrom(context);
- childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+ childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(relDims.ipd);
childLC.setWritingMode(getBlockContainerFO().getWritingMode());
if (curLM == this.childLMs.get(0)) {
@@ -578,7 +583,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
childLC = new LayoutContext(0);
childLC.copyPendingMarksFrom(context);
// curLM is a ?
- childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+ childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(relDims.ipd);
childLC.setWritingMode(getBlockContainerFO().getWritingMode());
if (curLM == this.childLMs.get(0)) {
@@ -649,41 +654,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
wrapPositionElements(contentList, returnList);
} else {
- MinOptMax range = new MinOptMax(relDims.ipd);
- BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
- breaker.doLayout(relDims.bpd, autoHeight);
- boolean contentOverflows = breaker.isOverflow();
- if (autoHeight) {
- //Update content BPD now that it is known
- int newHeight = breaker.deferredAlg.totalWidth;
- boolean switchedProgressionDirection
- = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
- if (switchedProgressionDirection) {
- setContentAreaIPD(newHeight);
- } else {
- vpContentBPD = newHeight;
- }
- updateRelDims(contentRectOffsetX, contentRectOffsetY, false);
- }
-
- Position bcPosition = new BlockContainerPosition(this, breaker);
- returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false));
- //TODO Handle min/opt/max for block-progression-dimension
- /* These two elements will be used to add stretchability to the above box
- returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
- false, returnPosition, false));
- returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
- LINE_NUMBER_ADJUSTMENT, returnPosition, false));
- */
-
- if (contentOverflows) {
- BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
- getBlockContainerFO().getUserAgent().getEventBroadcaster());
- boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
- eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
- breaker.getOverflowAmount(), needClip(), canRecover,
- getBlockContainerFO().getLocator());
- }
+ returnList.add(refactoredBecauseOfDuplicateCode(contentRectOffsetX,
+ contentRectOffsetY));
}
addKnuthElementsForBorderPaddingAfter(returnList, true);
addKnuthElementsForSpaceAfter(returnList, alignment);
@@ -706,8 +678,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
private List getNextKnuthElementsAbsolute(LayoutContext context, int alignment) {
autoHeight = false;
- boolean switchedProgressionDirection
- = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
+ boolean bpDirectionChanges = blockProgressionDirectionChanges();
Point offset = getAbsOffset();
int allocBPD, allocIPD;
if (height.getEnum() == EN_AUTO
@@ -720,7 +691,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
if (isFixed()) {
availHeight = (int)getCurrentPV().getViewArea().getHeight();
} else {
- availHeight = context.getStackLimitBP().opt;
+ availHeight = context.getStackLimitBP().getOpt();
}
allocBPD = availHeight;
allocBPD -= offset.y;
@@ -753,8 +724,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
}
}
} else {
- allocBPD = context.getStackLimitBP().opt;
- if (!switchedProgressionDirection) {
+ allocBPD = context.getStackLimitBP().getOpt();
+ if (!bpDirectionChanges) {
autoHeight = true;
}
}
@@ -798,7 +769,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
*/
allocIPD = 0;
}
- if (switchedProgressionDirection) {
+ if (bpDirectionChanges) {
autoHeight = true;
}
}
@@ -812,14 +783,14 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
updateRelDims(0, 0, autoHeight);
- MinOptMax range = new MinOptMax(relDims.ipd);
+ MinOptMax range = MinOptMax.getInstance(relDims.ipd);
BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight);
boolean contentOverflows = breaker.isOverflow();
if (autoHeight) {
//Update content BPD now that it is known
int newHeight = breaker.deferredAlg.totalWidth;
- if (switchedProgressionDirection) {
+ if (bpDirectionChanges) {
setContentAreaIPD(newHeight);
} else {
vpContentBPD = newHeight;
@@ -928,7 +899,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
protected LayoutContext createLayoutContext() {
LayoutContext lc = super.createLayoutContext();
- lc.setRefIPD(ipd.opt);
+ lc.setRefIPD(ipd.getOpt());
lc.setWritingMode(getBlockContainerFO().getWritingMode());
return lc;
}
@@ -1026,7 +997,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
// if this will create the first block area in a page
// and display-align is bottom or center, add space before
if (layoutContext.getSpaceBefore() > 0) {
- addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
+ addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
LayoutManager childLM;
@@ -1150,20 +1121,20 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
foBlockSpaceAfter = new SpaceVal(getBlockContainerFO()
.getCommonMarginBlock().spaceAfter, this).getSpace();
adjustedSpaceBefore = (neededUnits(splitLength
- + foBlockSpaceBefore.min
- + foBlockSpaceAfter.min)
+ + foBlockSpaceBefore.getMin()
+ + foBlockSpaceAfter.getMin())
* bpUnit - splitLength) / 2;
adjustedSpaceAfter = neededUnits(splitLength
- + foBlockSpaceBefore.min
- + foBlockSpaceAfter.min)
+ + foBlockSpaceBefore.getMin()
+ + foBlockSpaceAfter.getMin())
* bpUnit - splitLength - adjustedSpaceBefore;
} else if (bSpaceBefore) {
adjustedSpaceBefore = neededUnits(splitLength
- + foBlockSpaceBefore.min)
+ + foBlockSpaceBefore.getMin())
* bpUnit - splitLength;
} else {
adjustedSpaceAfter = neededUnits(splitLength
- + foBlockSpaceAfter.min)
+ + foBlockSpaceAfter.getMin())
* bpUnit - splitLength;
}
//log.debug("space before = " + adjustedSpaceBefore
@@ -1209,8 +1180,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
*/
public Area getParentArea(Area childArea) {
if (referenceArea == null) {
- boolean switchedProgressionDirection
- = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
+ boolean switchedProgressionDirection = blockProgressionDirectionChanges();
boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection;
viewportBlockArea = new BlockViewport(allowBPDUpdate);
@@ -1270,7 +1240,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
// Set up dimensions
// Must get dimensions from parent area
- /*Area parentArea =*/ parentLM.getParentArea(referenceArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(referenceArea);
//int referenceIPD = parentArea.getIPD();
referenceArea.setIPD(relDims.ipd);
// Get reference IPD from parentArea
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index d7453a399..69e07a404 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -241,7 +241,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// if this will create the first block area in a page
// and display-align is after or center, add space before
if (layoutContext.getSpaceBefore() > 0) {
- addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
+ addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
LayoutManager childLM;
@@ -356,20 +356,20 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
foSpaceAfter = new SpaceVal(getBlockFO()
.getCommonMarginBlock().spaceAfter, this).getSpace();
adjustedSpaceBefore = (neededUnits(splitLength
- + foSpaceBefore.min
- + foSpaceAfter.min)
+ + foSpaceBefore.getMin()
+ + foSpaceAfter.getMin())
* bpUnit - splitLength) / 2;
adjustedSpaceAfter = neededUnits(splitLength
- + foSpaceBefore.min
- + foSpaceAfter.min)
+ + foSpaceBefore.getMin()
+ + foSpaceAfter.getMin())
* bpUnit - splitLength - adjustedSpaceBefore;
} else if (spaceBefore) {
adjustedSpaceBefore = neededUnits(splitLength
- + foSpaceBefore.min)
+ + foSpaceBefore.getMin())
* bpUnit - splitLength;
} else {
adjustedSpaceAfter = neededUnits(splitLength
- + foSpaceAfter.min)
+ + foSpaceAfter.getMin())
* bpUnit - splitLength;
}
//log.debug("spazio prima = " + adjustedSpaceBefore
@@ -426,7 +426,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// Must get dimensions from parent area
//Don't optimize this line away. It can have ugly side-effects.
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
// set traits
TraitSetter.setProducerID(curBlockArea, getBlockFO().getId());
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java
index 3d30abde0..a1d43dd6f 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java
@@ -26,17 +26,6 @@ import org.apache.fop.fo.properties.KeepProperty;
*/
public interface BlockLevelLayoutManager extends LayoutManager {
- /** Adjustment class: no adjustment */
- int NO_ADJUSTMENT = -1;
- /** Adjustment class: adjustment for space-before */
- int SPACE_BEFORE_ADJUSTMENT = 0;
- /** Adjustment class: adjustment for space-after */
- int SPACE_AFTER_ADJUSTMENT = 1;
- /** Adjustment class: adjustment for number of lines */
- int LINE_NUMBER_ADJUSTMENT = 2;
- /** Adjustment class: adjustment for line height */
- int LINE_HEIGHT_ADJUSTMENT = 3;
-
int negotiateBPDAdjustment(int adj, KnuthElement lastElement);
void discardSpace(KnuthGlue spaceGlue);
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 92a423098..4636cb15a 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -128,7 +128,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
if (sp != 0) {
Block spacer = new Block();
spacer.setBPD(sp);
- parentLM.addChildArea(spacer);
+ parentLayoutManager.addChildArea(spacer);
}
}
@@ -177,7 +177,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
*/
protected void flush() {
if (getCurrentArea() != null) {
- parentLM.addChildArea(getCurrentArea());
+ parentLayoutManager.addChildArea(getCurrentArea());
}
}
@@ -654,7 +654,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
if (innerPosition == null && lastElement.isGlue()) {
// this adjustment applies to space-before or space-after of this block
- if (((KnuthGlue) lastElement).getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
+ if (((KnuthGlue) lastElement).getAdjustmentClass()
+ == Adjustment.SPACE_BEFORE_ADJUSTMENT) {
// this adjustment applies to space-before
adjustedSpaceBefore += adj;
/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> spazio prima: " + adj);
@@ -735,14 +736,14 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// if this block has block-progression-unit > 0, innerPosition can be
// a MappingPosition
// spaceGlue represents space before or space after of this block
- if (spaceGlue.getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
+ if (spaceGlue.getAdjustmentClass() == Adjustment.SPACE_BEFORE_ADJUSTMENT) {
// space-before must be discarded
adjustedSpaceBefore = 0;
- foSpaceBefore = new MinOptMax(0);
+ foSpaceBefore = MinOptMax.ZERO;
} else {
// space-after must be discarded
adjustedSpaceAfter = 0;
- foSpaceAfter = new MinOptMax(0);
+ foSpaceAfter = MinOptMax.ZERO;
//TODO Why are both cases handled in the same way?
}
} else {
@@ -909,10 +910,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
if (bpUnit > 0) {
returnList.add(new KnuthGlue(0, 0, 0,
- SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
+ Adjustment.SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
} else {
returnList.add(new KnuthGlue(adjustedSpaceBefore, 0, 0,
- SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
+ Adjustment.SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
}
}
@@ -949,12 +950,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
if (bpUnit > 0) {
returnList.add(new KnuthGlue(0, 0, 0,
- SPACE_AFTER_ADJUSTMENT,
+ Adjustment.SPACE_AFTER_ADJUSTMENT,
new NonLeafPosition(this, null),
spaceAfterIsConditional));
} else {
returnList.add(new KnuthGlue(adjustedSpaceAfter, 0, 0,
- SPACE_AFTER_ADJUSTMENT,
+ Adjustment.SPACE_AFTER_ADJUSTMENT,
new NonLeafPosition(this, null),
spaceAfterIsConditional));
}
@@ -1396,8 +1397,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
bAddedBoxAfter = true;
}
- MinOptMax totalLength = new MinOptMax(0);
- MinOptMax totalUnits = new MinOptMax(0);
+ MinOptMax totalLength = MinOptMax.ZERO;
LinkedList newList = new LinkedList();
//log.debug(" Prima scansione");
@@ -1406,11 +1406,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
while (oldListIterator.hasNext()) {
KnuthElement element = (KnuthElement) oldListIterator.next();
if (element.isBox()) {
- totalLength.add(new MinOptMax(element.getWidth()));
+ totalLength = totalLength.plus(element.getWidth());
//log.debug("box " + element.getWidth());
} else if (element.isGlue()) {
- totalLength.min -= element.getShrink();
- totalLength.max += element.getStretch();
+ totalLength = totalLength.minusMin(element.getShrink());
+ totalLength = totalLength.plusMax(element.getStretch());
//leafValue = ((LeafPosition) element.getPosition()).getLeafPos();
//log.debug("glue " + element.getWidth() + " + "
// + ((KnuthGlue) element).getStretch() + " - "
@@ -1421,9 +1421,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
}
// compute the total amount of "units"
- totalUnits = new MinOptMax(neededUnits(totalLength.min),
- neededUnits(totalLength.opt),
- neededUnits(totalLength.max));
+ MinOptMax totalUnits = MinOptMax.getInstance(neededUnits(totalLength.getMin()),
+ neededUnits(totalLength.getOpt()),
+ neededUnits(totalLength.getMax()));
//log.debug(" totalLength= " + totalLength);
//log.debug(" unita'= " + totalUnits);
@@ -1432,35 +1432,35 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// in order to compute partial min, opt and max length
// and create the new elements
oldListIterator = oldList.listIterator();
- boolean bPrevIsBox = false;
- MinOptMax lengthBeforeBreak = new MinOptMax(0);
- MinOptMax lengthAfterBreak = (MinOptMax) totalLength.clone();
+ boolean prevIsBox;
+ MinOptMax lengthBeforeBreak = MinOptMax.ZERO;
+ MinOptMax lengthAfterBreak = totalLength;
MinOptMax unitsBeforeBreak;
MinOptMax unitsAfterBreak;
- MinOptMax unsuppressibleUnits = new MinOptMax(0);
+ MinOptMax unsuppressibleUnits = MinOptMax.ZERO;
int firstIndex = 0;
int lastIndex = -1;
while (oldListIterator.hasNext()) {
KnuthElement element = (KnuthElement) oldListIterator.next();
lastIndex++;
if (element.isBox()) {
- lengthBeforeBreak.add(new MinOptMax(element.getWidth()));
- lengthAfterBreak.subtract(new MinOptMax(element.getWidth()));
- bPrevIsBox = true;
+ lengthBeforeBreak = lengthBeforeBreak.plus(element.getWidth());
+ lengthAfterBreak = lengthAfterBreak.minus(element.getWidth());
+ prevIsBox = true;
} else if (element.isGlue()) {
- lengthBeforeBreak.min -= element.getShrink();
- lengthAfterBreak.min += element.getShrink();
- lengthBeforeBreak.max += element.getStretch();
- lengthAfterBreak.max -= element.getStretch();
- bPrevIsBox = false;
+ lengthBeforeBreak = lengthBeforeBreak.minusMin(element.getShrink());
+ lengthAfterBreak = lengthAfterBreak.plusMin(element.getShrink());
+ lengthBeforeBreak = lengthBeforeBreak.plusMax(element.getStretch());
+ lengthAfterBreak = lengthAfterBreak.minusMax(element.getStretch());
+ prevIsBox = false;
} else {
- lengthBeforeBreak.add(new MinOptMax(element.getWidth()));
- bPrevIsBox = false;
+ lengthBeforeBreak = lengthBeforeBreak.plus(element.getWidth());
+ prevIsBox = false;
}
// create the new elements
if (element.isPenalty() && element.getPenalty() < KnuthElement.INFINITE
- || element.isGlue() && bPrevIsBox
+ || element.isGlue() && prevIsBox
|| !oldListIterator.hasNext()) {
// suppress elements after the breaking point
int iStepsForward = 0;
@@ -1469,8 +1469,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
iStepsForward++;
if (el.isGlue()) {
// suppressed glue
- lengthAfterBreak.min += el.getShrink();
- lengthAfterBreak.max -= el.getStretch();
+ lengthAfterBreak = lengthAfterBreak.plusMin(el.getShrink());
+ lengthAfterBreak = lengthAfterBreak.minusMax(el.getStretch());
} else if (el.isPenalty()) {
// suppressed penalty, do nothing
} else {
@@ -1479,36 +1479,37 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
}
// compute the partial amount of "units" before and after the break
- unitsBeforeBreak = new MinOptMax(neededUnits(lengthBeforeBreak.min),
- neededUnits(lengthBeforeBreak.opt),
- neededUnits(lengthBeforeBreak.max));
- unitsAfterBreak = new MinOptMax(neededUnits(lengthAfterBreak.min),
- neededUnits(lengthAfterBreak.opt),
- neededUnits(lengthAfterBreak.max));
+ unitsBeforeBreak = MinOptMax.getInstance(neededUnits(lengthBeforeBreak.getMin()),
+ neededUnits(lengthBeforeBreak.getOpt()),
+ neededUnits(lengthBeforeBreak.getMax()));
+ unitsAfterBreak = MinOptMax.getInstance(neededUnits(lengthAfterBreak.getMin()),
+ neededUnits(lengthAfterBreak.getOpt()),
+ neededUnits(lengthAfterBreak.getMax()));
// rewind the iterator and lengthAfterBreak
for (int i = 0; i < iStepsForward; i++) {
KnuthElement el = (KnuthElement) oldListIterator.previous();
if (el.isGlue()) {
- lengthAfterBreak.min -= el.getShrink();
- lengthAfterBreak.max += el.getStretch();
+ lengthAfterBreak = lengthAfterBreak.minusMin(el.getShrink());
+ lengthAfterBreak = lengthAfterBreak.plusMax(el.getStretch());
}
}
// compute changes in length, stretch and shrink
- int uLengthChange = unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt;
- int uStretchChange = (unitsBeforeBreak.max + unitsAfterBreak.max - totalUnits.max)
- - (unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt);
- int uShrinkChange = (unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt)
- - (unitsBeforeBreak.min + unitsAfterBreak.min - totalUnits.min);
+ int uLengthChange = unitsBeforeBreak.getOpt() + unitsAfterBreak.getOpt()
+ - totalUnits.getOpt();
+ int uStretchChange = unitsBeforeBreak.getStretch()
+ + unitsAfterBreak.getStretch() - totalUnits.getStretch();
+ int uShrinkChange = unitsBeforeBreak.getShrink()
+ + unitsAfterBreak.getShrink() - totalUnits.getShrink();
// compute the number of normal, stretch and shrink unit
// that must be added to the new sequence
- int uNewNormal = unitsBeforeBreak.opt - unsuppressibleUnits.opt;
- int uNewStretch = (unitsBeforeBreak.max - unitsBeforeBreak.opt)
- - (unsuppressibleUnits.max - unsuppressibleUnits.opt);
- int uNewShrink = (unitsBeforeBreak.opt - unitsBeforeBreak.min)
- - (unsuppressibleUnits.opt - unsuppressibleUnits.min);
+ int uNewNormal = unitsBeforeBreak.getOpt() - unsuppressibleUnits.getOpt();
+ int uNewStretch = unitsBeforeBreak.getStretch()
+ - unsuppressibleUnits.getStretch();
+ int uNewShrink = unitsBeforeBreak.getShrink()
+ - unsuppressibleUnits.getShrink();
//log.debug("("
// + unsuppressibleUnits.min + "-" + unsuppressibleUnits.opt + "-"
@@ -1539,10 +1540,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
lastIndex - lastIndexCorrection);
// new box
- newList.add(new KnuthBox((uNewNormal - uLengthChange) * bpUnit,
- mappingPos,
- false));
- unsuppressibleUnits.add(new MinOptMax(uNewNormal - uLengthChange));
+ newList.add(new KnuthBox((uNewNormal - uLengthChange) * bpUnit, mappingPos, false));
+ unsuppressibleUnits = unsuppressibleUnits.plus(uNewNormal - uLengthChange);
//log.debug(" box " + (uNewNormal - uLengthChange));
// new infinite penalty, glue and box, if necessary
@@ -1558,17 +1557,15 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
newList.add(new KnuthGlue(0,
iStretchUnits * bpUnit,
iShrinkUnits * bpUnit,
- LINE_NUMBER_ADJUSTMENT,
+ Adjustment.LINE_NUMBER_ADJUSTMENT,
mappingPos,
false));
//log.debug(" PENALTY");
//log.debug(" glue 0 " + iStretchUnits + " " + iShrinkUnits);
- unsuppressibleUnits.max += iStretchUnits;
- unsuppressibleUnits.min -= iShrinkUnits;
+ unsuppressibleUnits = unsuppressibleUnits.plusMax(iStretchUnits);
+ unsuppressibleUnits = unsuppressibleUnits.minusMin(iShrinkUnits);
if (!oldListIterator.hasNext()) {
- newList.add(new KnuthBox(0,
- mappingPos,
- false));
+ newList.add(new KnuthBox(0, mappingPos, false));
//log.debug(" box 0");
}
}
@@ -1583,7 +1580,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
newList.add(new KnuthGlue(0,
uStretchChange * bpUnit,
uShrinkChange * bpUnit,
- LINE_NUMBER_ADJUSTMENT,
+ Adjustment.LINE_NUMBER_ADJUSTMENT,
mappingPos,
false));
newList.add(new KnuthPenalty(uLengthChange * bpUnit,
@@ -1591,7 +1588,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
newList.add(new KnuthGlue(0,
-uStretchChange * bpUnit,
-uShrinkChange * bpUnit,
- LINE_NUMBER_ADJUSTMENT,
+ Adjustment.LINE_NUMBER_ADJUSTMENT,
mappingPos,
false));
//log.debug(" PENALTY");
@@ -1612,7 +1609,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
if (element.isPenalty()) {
- lengthBeforeBreak.add(new MinOptMax(-element.getWidth()));
+ lengthBeforeBreak = lengthBeforeBreak.minus(element.getWidth());
}
}
@@ -1637,13 +1634,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
KnuthBox wrongBox = (KnuthBox) newList.removeFirst();
// if this paragraph is at the top of a page, the space before
// must be ignored; compute the length change
- int decreasedLength = (neededUnits(totalLength.opt)
- - neededUnits(totalLength.opt - adjustedSpaceBefore))
+ int decreasedLength = (neededUnits(totalLength.getOpt())
+ - neededUnits(totalLength.getOpt() - adjustedSpaceBefore))
* bpUnit;
// insert the correct elements
newList.addFirst(new KnuthBox(wrongBox.getWidth() - decreasedLength,
wrongBox.getPosition(), false));
- newList.addFirst(new KnuthGlue(decreasedLength, 0, 0, SPACE_BEFORE_ADJUSTMENT,
+ newList.addFirst(new KnuthGlue(decreasedLength, 0, 0, Adjustment.SPACE_BEFORE_ADJUSTMENT,
wrongBox.getPosition(), false));
//log.debug(" rimosso box " + neededUnits(wrongBox.getWidth()));
//log.debug(" aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
@@ -1673,8 +1670,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// if this paragraph is at the bottom of a page, the space after
// must be ignored; compute the length change
- int decreasedLength = (neededUnits(totalLength.opt)
- - neededUnits(totalLength.opt - adjustedSpaceAfter))
+ int decreasedLength = (neededUnits(totalLength.getOpt())
+ - neededUnits(totalLength.getOpt() - adjustedSpaceAfter))
* bpUnit;
// insert the correct box
newList.addLast(new KnuthBox(wrongBox.getWidth() - decreasedLength,
@@ -1684,7 +1681,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
newList.addAll(preserveList);
}
// insert the correct glue
- newList.addLast(new KnuthGlue(decreasedLength, 0, 0, SPACE_AFTER_ADJUSTMENT,
+ newList.addLast(new KnuthGlue(decreasedLength, 0, 0, Adjustment.SPACE_AFTER_ADJUSTMENT,
wrongBox.getPosition(), false));
//log.debug(" rimosso box " + neededUnits(wrongBox.getWidth()));
//log.debug(" aggiunto box " + neededUnits(
@@ -1773,8 +1770,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
*/
protected void wrapPositionElement(ListElement el, List targetList, boolean force) {
if (force || el.getLayoutManager() != this) {
- el.setPosition(notifyPos(new NonLeafPosition(this,
- el.getPosition())));
+ el.setPosition(notifyPos(new NonLeafPosition(this, el.getPosition())));
}
targetList.add(el);
}
diff --git a/src/java/org/apache/fop/layoutmgr/BorderOrPaddingElement.java b/src/java/org/apache/fop/layoutmgr/BorderOrPaddingElement.java
index 28820224a..5236c9234 100644
--- a/src/java/org/apache/fop/layoutmgr/BorderOrPaddingElement.java
+++ b/src/java/org/apache/fop/layoutmgr/BorderOrPaddingElement.java
@@ -41,7 +41,7 @@ public abstract class BorderOrPaddingElement extends UnresolvedListElementWithLe
RelSide side,
boolean isFirst, boolean isLast, PercentBaseContext context) {
super(position,
- new MinOptMax(condLength.getLength().getValue(context)), side,
+ MinOptMax.getInstance(condLength.getLength().getValue(context)), side,
condLength.isDiscard(), isFirst, isLast);
}
diff --git a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
index ca11d27c2..6a843ac63 100644
--- a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
+++ b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
@@ -43,7 +43,7 @@ public final class ElementListUtils {
* @return true if the opt constraint is bigger than the list contents
*/
public static boolean removeLegalBreaks(List elements, MinOptMax constraint) {
- return removeLegalBreaks(elements, constraint.opt);
+ return removeLegalBreaks(elements, constraint.getOpt());
}
/**
@@ -132,7 +132,7 @@ public final class ElementListUtils {
}
} else if (el instanceof UnresolvedListElementWithLength) {
UnresolvedListElementWithLength uel = (UnresolvedListElementWithLength)el;
- len += uel.getLength().opt;
+ len += uel.getLength().getOpt();
}
} else {
KnuthElement kel = (KnuthElement)el;
@@ -240,4 +240,4 @@ public final class ElementListUtils {
return prevBreak;
}
-} \ No newline at end of file
+}
diff --git a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
index affa75abb..4f6cfa9d5 100644
--- a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
@@ -83,7 +83,7 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager {
/** {@inheritDoc} */
public void addChildArea(Area childArea) {
childArea.setAreaClass(Area.CLASS_FOOTNOTE);
- parentLM.addChildArea(childArea);
+ parentLayoutManager.addChildArea(childArea);
}
/** @return the FootnoteBody node */
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java b/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java
index 1aa22ea3e..a7fc5bb72 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java
@@ -41,30 +41,32 @@ public class KnuthBlockBox extends KnuthBox {
/**
* Creates a new box.
- * @param w block progression dimension of this box
- * @param range min, opt, max inline progression dimension of this box
- * @param bpdim natural width of the line represented by this box.
- * @param pos the Position stored in this box
- * @param bAux is this box auxiliary?
+ *
+ * @param width block progression dimension of this box
+ * @param range min, opt, max inline progression dimension of this box
+ * @param bpdim natural width of the line represented by this box.
+ * @param pos the Position stored in this box
+ * @param auxiliary is this box auxiliary?
*/
- public KnuthBlockBox(int w, MinOptMax range, int bpdim, Position pos, boolean bAux) {
- super(w, pos, bAux);
- ipdRange = (MinOptMax) range.clone();
+ public KnuthBlockBox(int width, MinOptMax range, int bpdim, Position pos, boolean auxiliary) {
+ super(width, pos, auxiliary);
+ ipdRange = range;
bpd = bpdim;
footnoteList = new LinkedList();
}
/**
* Creates a new box.
- * @param w block progression dimension of this box
- * @param list footnotes cited by elements in this box. The list contains the
- * corresponding FootnoteBodyLayoutManagers
- * @param pos the Position stored in this box
- * @param bAux is this box auxiliary?
+ *
+ * @param width block progression dimension of this box
+ * @param list footnotes cited by elements in this box. The list contains the corresponding
+ * FootnoteBodyLayoutManagers
+ * @param pos the Position stored in this box
+ * @param auxiliary is this box auxiliary?
*/
- public KnuthBlockBox(int w, List list, Position pos, boolean bAux) {
- super(w, pos, bAux);
- ipdRange = new MinOptMax(0);
+ public KnuthBlockBox(int width, List list, Position pos, boolean auxiliary) {
+ super(width, pos, auxiliary);
+ ipdRange = MinOptMax.ZERO;
bpd = 0;
footnoteList = new LinkedList(list);
}
@@ -85,6 +87,7 @@ public class KnuthBlockBox extends KnuthBox {
/**
* Adds the given list of Knuth elements to this box' list of elements.
+ *
* @param list elements corresponding to a footnote body
*/
public void addElementList(List list) {
@@ -96,8 +99,8 @@ public class KnuthBlockBox extends KnuthBox {
/**
* Returns the list of Knuth sequences registered by this box.
- * @return a list of KnuthElement sequences corresponding to footnotes cited in this
- * box
+ *
+ * @return a list of KnuthElement sequences corresponding to footnotes cited in this box
*/
public List getElementLists() {
return elementLists;
@@ -107,12 +110,13 @@ public class KnuthBlockBox extends KnuthBox {
* @return the inline progression dimension of this box.
*/
public MinOptMax getIPDRange() {
- return (MinOptMax) ipdRange.clone();
+ return ipdRange;
}
/**
- * Returns the natural width (without stretching nor shrinking) of the line
- * represented by this box.
+ * Returns the natural width (without stretching nor shrinking) of the line represented by this
+ * box.
+ *
* @return the line width
*/
public int getBPD() {
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthBox.java b/src/java/org/apache/fop/layoutmgr/KnuthBox.java
index d7615dda1..a1d8c095c 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthBox.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthBox.java
@@ -35,7 +35,7 @@ package org.apache.fop.layoutmgr;
public class KnuthBox extends KnuthElement {
/**
- * Create a new KnuthBox.
+ * Creates a new <code>KnuthBox</code>.
*
* @param width the width of this box
* @param pos the Position stored in this box
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthElement.java b/src/java/org/apache/fop/layoutmgr/KnuthElement.java
index e8ca6d85b..acd95a7d6 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthElement.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthElement.java
@@ -36,8 +36,7 @@ public abstract class KnuthElement extends ListElement {
private boolean auxiliary;
/**
- * Create a new KnuthElement.
- * This class being abstract, this can be called only by subclasses.
+ * Creates a new <code>KnuthElement</code>.
*
* @param width the width of this element
* @param pos the Position stored in this element
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthGlue.java b/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
index 7533a4117..2efea0e61 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
@@ -19,6 +19,8 @@
package org.apache.fop.layoutmgr;
+import org.apache.fop.traits.MinOptMax;
+
/**
* An instance of this class represents a piece of content with adjustable
* width: for example a space between words of justified text.
@@ -47,31 +49,49 @@ package org.apache.fop.layoutmgr;
*/
public class KnuthGlue extends KnuthElement {
- private int stretchability;
- private int shrinkability;
- private int adjustmentClass = -1;
+ private final int stretch;
+ private final int shrink;
+ private final Adjustment adjustmentClass;
+
+ /**
+ * Creates a new <code>KnuthGlue</code>.
+ *
+ * @param minOptMax a <code>MinOptMax</code> where the {@link MinOptMax#getOpt() opt-value} is
+ * mapped to the width, the {@link MinOptMax#getStretch()
+ * stretchability} is mapped to the stretchability and the the {@link
+ * MinOptMax#getShrink() shrinkability} is mapped to the shrinkability
+ * @param pos the Position stored in this glue
+ * @param auxiliary is this glue auxiliary?
+ */
+ public KnuthGlue(MinOptMax minOptMax, Position pos, boolean auxiliary) {
+ super(minOptMax.getOpt(), pos, auxiliary);
+ this.stretch = minOptMax.getStretch();
+ this.shrink = minOptMax.getShrink();
+ this.adjustmentClass = Adjustment.NO_ADJUSTMENT;
+ }
/**
- * Create a new KnuthGlue.
+ * Creates a new <code>KnuthGlue</code>.
*
- * @param width the width of this glue
- * @param stretchability the stretchability of this glue
- * @param shrinkability the shrinkability of this glue
- * @param pos the Position stored in this glue
+ * @param width the width of this glue
+ * @param stretch the stretchability of this glue
+ * @param shrink the shrinkability of this glue
+ * @param pos the Position stored in this glue
* @param auxiliary is this glue auxiliary?
*/
- public KnuthGlue(int width, int stretchability, int shrinkability, Position pos,
+ public KnuthGlue(int width, int stretch, int shrink, Position pos,
boolean auxiliary) {
super(width, pos, auxiliary);
- this.stretchability = stretchability;
- this.shrinkability = shrinkability;
+ this.stretch = stretch;
+ this.shrink = shrink;
+ this.adjustmentClass = Adjustment.NO_ADJUSTMENT;
}
- public KnuthGlue(int width, int stretchability, int shrinkability, int adjustmentClass,
+ public KnuthGlue(int width, int stretch, int shrink, Adjustment adjustmentClass,
Position pos, boolean auxiliary) {
super(width, pos, auxiliary);
- this.stretchability = stretchability;
- this.shrinkability = shrinkability;
+ this.stretch = stretch;
+ this.shrink = shrink;
this.adjustmentClass = adjustmentClass;
}
@@ -82,16 +102,16 @@ public class KnuthGlue extends KnuthElement {
/** @return the stretchability of this glue. */
public int getStretch() {
- return stretchability;
+ return stretch;
}
/** @return the shrinkability of this glue. */
public int getShrink() {
- return shrinkability;
+ return shrink;
}
/** @return the adjustment class (or role) of this glue. */
- public int getAdjustmentClass() {
+ public Adjustment getAdjustmentClass() {
return adjustmentClass;
}
@@ -105,7 +125,7 @@ public class KnuthGlue extends KnuthElement {
buffer.append(" w=").append(getWidth());
buffer.append(" stretch=").append(getStretch());
buffer.append(" shrink=").append(getShrink());
- if (getAdjustmentClass() >= 0) {
+ if (!getAdjustmentClass().equals(Adjustment.NO_ADJUSTMENT)) {
buffer.append(" adj-class=").append(getAdjustmentClass());
}
return buffer.toString();
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
index 81726e57b..752ffd628 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
@@ -173,7 +173,7 @@ public class LayoutContext {
public LayoutContext(int flags) {
this.flags = flags;
this.refIPD = 0;
- stackLimitBP = new MinOptMax(0);
+ stackLimitBP = MinOptMax.ZERO;
leadingSpace = null;
trailingSpace = null;
}
diff --git a/src/java/org/apache/fop/layoutmgr/LeafPosition.java b/src/java/org/apache/fop/layoutmgr/LeafPosition.java
index 8b2a5f4bc..e1d5b2aaa 100644
--- a/src/java/org/apache/fop/layoutmgr/LeafPosition.java
+++ b/src/java/org/apache/fop/layoutmgr/LeafPosition.java
@@ -23,8 +23,8 @@ public class LeafPosition extends Position {
private int leafPos;
- public LeafPosition(LayoutManager lm, int pos) {
- super(lm);
+ public LeafPosition(LayoutManager layoutManager, int pos) {
+ super(layoutManager);
leafPos = pos;
}
diff --git a/src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java b/src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java
deleted file mode 100644
index f029d9082..000000000
--- a/src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java
+++ /dev/null
@@ -1,115 +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.datatypes.PercentBaseContext;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.properties.LengthRangeProperty;
-import org.apache.fop.traits.MinOptMax;
-
-/**
- * Utilities for MinOptMax and LengthRangeProperty.
- */
-public class MinOptMaxUtil {
-
- /**
- * Restricts a MinOptMax using the values from a LengthRangeProperty.
- * @param mom MinOptMax to restrict
- * @param lr restricting source
- * @param context Percentage evaluation context
- */
- public static void restrict(MinOptMax mom, LengthRangeProperty lr,
- PercentBaseContext context) {
- if (lr.getEnum() != Constants.EN_AUTO) {
- if (lr.getMinimum(context).getEnum() != Constants.EN_AUTO) {
- int min = lr.getMinimum(context).getLength().getValue(context);
- if (min > mom.min) {
- mom.min = min;
- fixAfterMinChanged(mom);
- }
- }
- if (lr.getMaximum(context).getEnum() != Constants.EN_AUTO) {
- int max = lr.getMaximum(context).getLength().getValue(context);
- if (max < mom.max) {
- mom.max = max;
- if (mom.max < mom.opt) {
- mom.opt = mom.max;
- mom.min = mom.opt;
- }
- }
- }
- if (lr.getOptimum(context).getEnum() != Constants.EN_AUTO) {
- int opt = lr.getOptimum(context).getLength().getValue(context);
- if (opt > mom.min) {
- mom.opt = opt;
- if (mom.opt > mom.max) {
- mom.max = mom.opt;
- }
- }
- }
- }
- }
-
- /**
- * Extends the minimum length to the given length if necessary, and adjusts opt and
- * max accordingly.
- *
- * @param mom the min/opt/max trait
- * @param len the new minimum length
- */
- public static void extendMinimum(MinOptMax mom, int len) {
- if (mom.min < len) {
- mom.min = len;
- mom.opt = Math.max(mom.min, mom.opt);
- mom.max = Math.max(mom.opt, mom.max);
- }
- }
-
- /**
- * After a calculation on a MinOptMax, this can be called to set opt to
- * a new effective value.
- * @param mom MinOptMax to adjust
- */
- public static void fixAfterMinChanged(MinOptMax mom) {
- if (mom.min > mom.opt) {
- mom.opt = mom.min;
- if (mom.opt > mom.max) {
- mom.max = mom.opt;
- }
- }
- }
-
- /**
- * Converts a LengthRangeProperty to a MinOptMax.
- * @param prop LengthRangeProperty
- * @param context Percentage evaluation context
- * @return the requested MinOptMax instance
- */
- public static MinOptMax toMinOptMax(LengthRangeProperty prop, PercentBaseContext context) {
- int min = prop.getMinimum(context).isAuto() ? 0
- : prop.getMinimum(context).getLength().getValue(context);
- int opt = prop.getOptimum(context).isAuto() ? min
- : prop.getOptimum(context).getLength().getValue(context);
- int max = prop.getMaximum(context).isAuto() ? Integer.MAX_VALUE
- : prop.getMaximum(context).getLength().getValue(context);
- return new MinOptMax(min, opt, max);
- }
-
-}
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
index 86c3fccf8..134e69f31 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.layoutmgr;
-import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -204,7 +203,7 @@ public class PageBreaker extends AbstractBreaker {
pslm, footnoteSeparator, separatorArea);
footnoteSeparatorLM.doLayout();
- footnoteSeparatorLength = new MinOptMax(separatorArea.getBPD());
+ footnoteSeparatorLength = MinOptMax.getInstance(separatorArea.getBPD());
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
index cab68a13f..8f60e51b7 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
@@ -116,7 +116,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
this.pageProvider = pageProvider;
this.layoutListener = layoutListener;
best = new BestPageRecords();
- this.footnoteSeparatorLength = (MinOptMax) footnoteSeparatorLength.clone();
+ this.footnoteSeparatorLength = footnoteSeparatorLength;
this.autoHeight = autoHeight;
this.favorSinglePart = favorSinglePart;
}
@@ -483,7 +483,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
if (allFootnotes > 0) {
// this page contains some footnote citations
// add the footnote separator width
- actualWidth += footnoteSeparatorLength.opt;
+ actualWidth += footnoteSeparatorLength.getOpt();
if (actualWidth + allFootnotes <= getLineWidth(activeNode.line)) {
// there is enough space to insert all footnotes:
// add the whole allFootnotes length
@@ -757,7 +757,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int maxAdjustment = totalStretch - activeNode.totalStretch;
// add the footnote separator stretch if some footnote content will be added
if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
- maxAdjustment += footnoteSeparatorLength.max - footnoteSeparatorLength.opt;
+ maxAdjustment += footnoteSeparatorLength.getStretch();
}
if (maxAdjustment > 0) {
return (double) difference / maxAdjustment;
@@ -768,7 +768,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int maxAdjustment = totalShrink - activeNode.totalShrink;
// add the footnote separator shrink if some footnote content will be added
if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
- maxAdjustment += footnoteSeparatorLength.opt - footnoteSeparatorLength.min;
+ maxAdjustment += footnoteSeparatorLength.getShrink();
}
if (maxAdjustment > 0) {
return (double) difference / maxAdjustment;
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceElement.java b/src/java/org/apache/fop/layoutmgr/SpaceElement.java
index 820cf6506..6590d3a2a 100644
--- a/src/java/org/apache/fop/layoutmgr/SpaceElement.java
+++ b/src/java/org/apache/fop/layoutmgr/SpaceElement.java
@@ -40,13 +40,10 @@ public class SpaceElement extends UnresolvedListElementWithLength {
* @param isLast true if this is a space-after of the last area generated.
* @param context the property evaluation context
*/
- public SpaceElement(Position position, SpaceProperty space, RelSide side,
- boolean isFirst, boolean isLast,
- PercentBaseContext context) {
- super(position,
- MinOptMaxUtil.toMinOptMax(
- space.getSpace().getLengthRange(),
- context), side, space.isDiscard(), isFirst, isLast);
+ public SpaceElement(Position position, SpaceProperty space, RelSide side, boolean isFirst,
+ boolean isLast, PercentBaseContext context) {
+ super(position, space.getSpace().getLengthRange().toMinOptMax(context), side,
+ space.isDiscard(), isFirst, isLast);
int en = space.getSpace().getPrecedence().getEnum();
if (en == Constants.EN_FORCE) {
this.precedence = Integer.MAX_VALUE;
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
index ff464ce6a..6dbf107f3 100644
--- a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
+++ b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
@@ -152,7 +152,7 @@ public class SpaceResolver {
}
private void removeConditionalBorderAndPadding(
- UnresolvedListElement[] elems, MinOptMax[] lengths, boolean reverse) {
+ UnresolvedListElement[] elems, MinOptMax[] lengths, boolean reverse) {
for (int i = 0; i < elems.length; i++) {
int effIndex;
if (reverse) {
@@ -176,7 +176,7 @@ public class SpaceResolver {
}
private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths,
- boolean reverse) {
+ boolean reverse) {
for (int i = 0; i < elems.length; i++) {
int effIndex;
if (reverse) {
@@ -274,7 +274,7 @@ public class SpaceResolver {
}
lengths[i] = null;
} else {
- greatestOptimum = Math.max(greatestOptimum, space.getLength().opt);
+ greatestOptimum = Math.max(greatestOptimum, space.getLength().getOpt());
remaining++;
}
}
@@ -291,7 +291,7 @@ public class SpaceResolver {
continue;
}
space = (SpaceElement)elems[i];
- if (space.getLength().opt < greatestOptimum) {
+ if (space.getLength().getOpt() < greatestOptimum) {
if (log.isDebugEnabled()) {
log.debug("Nulling space-specifier with smaller optimum length "
+ "using 4.3.1, rule 3: "
@@ -313,8 +313,8 @@ public class SpaceResolver {
continue;
}
space = (SpaceElement)elems[i];
- min = Math.max(min, space.getLength().min);
- max = Math.min(max, space.getLength().max);
+ min = Math.max(min, space.getLength().getMin());
+ max = Math.min(max, space.getLength().getMax());
if (remaining > 1) {
if (log.isDebugEnabled()) {
log.debug("Nulling non-last space-specifier using 4.3.1, rule 3, second part: "
@@ -323,8 +323,7 @@ public class SpaceResolver {
lengths[i] = null;
remaining--;
} else {
- lengths[i].min = min;
- lengths[i].max = max;
+ lengths[i] = MinOptMax.getInstance(min, lengths[i].getOpt(), max);
}
}
@@ -409,54 +408,27 @@ public class SpaceResolver {
}
private MinOptMax sum(MinOptMax[] lengths) {
- MinOptMax sum = new MinOptMax();
+ MinOptMax sum = MinOptMax.ZERO;
for (int i = 0; i < lengths.length; i++) {
if (lengths[i] != null) {
- sum.add(lengths[i]);
+ sum = sum.plus(lengths[i]);
}
}
return sum;
}
private void generate(ListIterator iter) {
- MinOptMax noBreakLength = new MinOptMax();
- MinOptMax glue1; //space before break possibility if break occurs
- //MinOptMax glue2; //difference between glue 1 and 3 when no break occurs
- MinOptMax glue3; //space after break possibility if break occurs
- glue1 = sum(firstPartLengths);
- glue3 = sum(secondPartLengths);
- noBreakLength = sum(noBreakLengths);
-
- //This doesn't produce the right glue2
- //glue2 = new MinOptMax(noBreakLength);
- //glue2.subtract(glue1);
- //glue2.subtract(glue3);
-
- int glue2w = noBreakLength.opt - glue1.opt - glue3.opt;
- int glue2stretch = (noBreakLength.max - noBreakLength.opt);
- int glue2shrink = (noBreakLength.opt - noBreakLength.min);
- glue2stretch -= glue1.max - glue1.opt;
- glue2stretch -= glue3.max - glue3.opt;
- glue2shrink -= glue1.opt - glue1.min;
- glue2shrink -= glue3.opt - glue3.min;
+ MinOptMax spaceBeforeBreak = sum(firstPartLengths);
+ MinOptMax spaceAfterBreak = sum(secondPartLengths);
boolean hasPrecedingNonBlock = false;
- if (log.isDebugEnabled()) {
- log.debug("noBreakLength=" + noBreakLength
- + ", glue1=" + glue1
- + ", glue2=" + glue2w + "+" + glue2stretch + "-" + glue2shrink
- + ", glue3=" + glue3);
- }
if (breakPoss != null) {
- boolean forcedBreak = breakPoss.isForcedBreak();
- if (glue1.isNonZero()) {
- iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE,
- false, (Position)null, true));
- iter.add(new KnuthGlue(glue1.opt, glue1.max - glue1.opt, glue1.opt - glue1.min,
- (Position)null, true));
- if (forcedBreak) {
+ if (spaceBeforeBreak.isNonZero()) {
+ iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, null, true));
+ iter.add(new KnuthGlue(spaceBeforeBreak, null, true));
+ if (breakPoss.isForcedBreak()) {
//Otherwise, the preceding penalty and glue will be cut off
- iter.add(new KnuthBox(0, (Position)null, true));
+ iter.add(new KnuthBox(0, null, true));
}
}
iter.add(new KnuthPenalty(breakPoss.getPenaltyWidth(), breakPoss.getPenaltyValue(),
@@ -465,32 +437,38 @@ public class SpaceResolver {
if (breakPoss.getPenaltyValue() <= -KnuthPenalty.INFINITE) {
return; //return early. Not necessary (even wrong) to add additional elements
}
- if (glue2w != 0 || glue2stretch != 0 || glue2shrink != 0) {
- iter.add(new KnuthGlue(glue2w, glue2stretch, glue2shrink,
- (Position)null, true));
+
+ // No break
+ // TODO: We can't use a MinOptMax for glue2, because min <= opt <= max is not always true - why?
+ MinOptMax noBreakLength = sum(noBreakLengths);
+ MinOptMax spaceSum = spaceBeforeBreak.plus(spaceAfterBreak);
+ int glue2width = noBreakLength.getOpt() - spaceSum.getOpt();
+ int glue2stretch = noBreakLength.getStretch() - spaceSum.getStretch();
+ int glue2shrink = noBreakLength.getShrink() - spaceSum.getShrink();
+
+ if (glue2width != 0 || glue2stretch != 0 || glue2shrink != 0) {
+ iter.add(new KnuthGlue(glue2width, glue2stretch, glue2shrink, null, true));
}
} else {
- if (glue1.isNonZero()) {
- throw new IllegalStateException("glue1 should be 0 in this case");
+ if (spaceBeforeBreak.isNonZero()) {
+ throw new IllegalStateException("spaceBeforeBreak should be 0 in this case");
}
}
Position pos = null;
if (breakPoss == null) {
pos = new SpaceHandlingPosition(this);
}
- if (glue3.isNonZero() || pos != null) {
+ if (spaceAfterBreak.isNonZero() || pos != null) {
iter.add(new KnuthBox(0, pos, true));
}
- if (glue3.isNonZero()) {
- iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE,
- false, (Position)null, true));
- iter.add(new KnuthGlue(glue3.opt, glue3.max - glue3.opt, glue3.opt - glue3.min,
- (Position)null, true));
+ if (spaceAfterBreak.isNonZero()) {
+ iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, null, true));
+ iter.add(new KnuthGlue(spaceAfterBreak, null, true));
hasPrecedingNonBlock = true;
}
if (isLast && hasPrecedingNonBlock) {
//Otherwise, the preceding penalty and glue will be cut off
- iter.add(new KnuthBox(0, (Position)null, true));
+ iter.add(new KnuthBox(0, null, true));
}
}
@@ -608,9 +586,7 @@ public class SpaceResolver {
/** {@inheritDoc} */
public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("SpaceHandlingPosition");
- return sb.toString();
+ return "SpaceHandlingPosition";
}
}
@@ -741,5 +717,4 @@ public class SpaceResolver {
}
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java b/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java
index 62a066121..140d90bb8 100644
--- a/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java
+++ b/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java
@@ -31,12 +31,10 @@ import org.apache.fop.traits.MinOptMax;
*/
public class SpaceSpecifier implements Cloneable {
-
private boolean startsReferenceArea;
private boolean hasForcing = false;
private List spaceVals = new ArrayList();
-
/**
* Creates a new SpaceSpecifier.
* @param startsReferenceArea true if it starts a new reference area
@@ -76,7 +74,7 @@ public class SpaceSpecifier implements Cloneable {
* @return true if any space-specifiers have been added.
*/
public boolean hasSpaces() {
- return (spaceVals.size() > 0);
+ return !spaceVals.isEmpty();
}
/**
@@ -84,24 +82,22 @@ public class SpaceSpecifier implements Cloneable {
* area, and the added space is conditional, and there are no
* non-conditional values in the sequence yet, then ignore it. Otherwise
* add it to the sequence.
+ *
+ * @param space the space to add.
*/
- public void addSpace(SpaceVal moreSpace) {
- if (!startsReferenceArea
- || !moreSpace.isConditional()
- || !spaceVals.isEmpty()) {
- if (moreSpace.isForcing()) {
+ public void addSpace(SpaceVal space) {
+ if (!startsReferenceArea || !space.isConditional() || hasSpaces()) {
+ if (space.isForcing()) {
if (!hasForcing) {
// Remove all other values (must all be non-forcing)
spaceVals.clear();
hasForcing = true;
}
- spaceVals.add(moreSpace);
+ spaceVals.add(space);
} else if (!hasForcing) {
// Don't bother adding all 0 space-specifier if not forcing
- if (moreSpace.getSpace().min != 0
- || moreSpace.getSpace().opt != 0
- || moreSpace.getSpace().max != 0) {
- spaceVals.add(moreSpace);
+ if (space.getSpace().isNonZero()) {
+ spaceVals.add(space);
}
}
}
@@ -109,11 +105,11 @@ public class SpaceSpecifier implements Cloneable {
/**
- * Resolve the current sequence of space-specifiers, accounting for
- * forcing values.
- * @param endsReferenceArea True if the sequence should be resolved
- * at the trailing edge of reference area.
- * @return The resolved value as a min/opt/max triple.
+ * Resolve the current sequence of space-specifiers, accounting for forcing values.
+ *
+ * @param endsReferenceArea whether the sequence should be resolved at the trailing edge of
+ * reference area.
+ * @return the resolved value as a min/opt/max triple.
*/
public MinOptMax resolve(boolean endsReferenceArea) {
int lastIndex = spaceVals.size();
@@ -127,24 +123,30 @@ public class SpaceSpecifier implements Cloneable {
}
}
}
- MinOptMax resolvedSpace = new MinOptMax(0);
+ MinOptMax resolvedSpace = MinOptMax.ZERO;
int maxPrecedence = -1;
for (int index = 0; index < lastIndex; index++) {
SpaceVal spaceVal = (SpaceVal) spaceVals.get(index);
+ MinOptMax space = spaceVal.getSpace();
if (hasForcing) {
- resolvedSpace.add(spaceVal.getSpace());
- } else if (spaceVal.getPrecedence() > maxPrecedence) {
- maxPrecedence = spaceVal.getPrecedence();
- resolvedSpace = spaceVal.getSpace();
- } else if (spaceVal.getPrecedence() == maxPrecedence) {
- if (spaceVal.getSpace().opt > resolvedSpace.opt) {
- resolvedSpace = spaceVal.getSpace();
- } else if (spaceVal.getSpace().opt == resolvedSpace.opt) {
- if (resolvedSpace.min < spaceVal.getSpace().min) {
- resolvedSpace.min = spaceVal.getSpace().min;
- }
- if (resolvedSpace.max > spaceVal.getSpace().max) {
- resolvedSpace.max = spaceVal.getSpace().max;
+ resolvedSpace = resolvedSpace.plus(space);
+ } else {
+ int precedence = spaceVal.getPrecedence();
+ if (precedence > maxPrecedence) {
+ maxPrecedence = precedence;
+ resolvedSpace = space;
+ } else if (precedence == maxPrecedence) {
+ if (space.getOpt() > resolvedSpace.getOpt()) {
+ resolvedSpace = space;
+ } else if (space.getOpt() == resolvedSpace.getOpt()) {
+ if (resolvedSpace.getMin() < space.getMin()) {
+ resolvedSpace = MinOptMax.getInstance(space.getMin(),
+ resolvedSpace.getOpt(), resolvedSpace.getMax());
+ }
+ if (resolvedSpace.getMax() > space.getMax()) {
+ resolvedSpace = MinOptMax.getInstance(resolvedSpace.getMin(),
+ resolvedSpace.getOpt(), space.getMax());
+ }
}
}
}
@@ -154,8 +156,7 @@ public class SpaceSpecifier implements Cloneable {
}
public String toString() {
- return "Space Specifier (resolved at begin/end of ref. area:):\n" +
- resolve(false).toString() + "\n" +
- resolve(true).toString();
+ return "Space Specifier (resolved at begin/end of ref. area:):\n"
+ + resolve(false) + "\n" + resolve(true);
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/TraitSetter.java b/src/java/org/apache/fop/layoutmgr/TraitSetter.java
index d062ba2ca..911b6dcc6 100644
--- a/src/java/org/apache/fop/layoutmgr/TraitSetter.java
+++ b/src/java/org/apache/fop/layoutmgr/TraitSetter.java
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.apache.fop.area.Area;
import org.apache.fop.area.Trait;
import org.apache.fop.datatypes.LengthBase;
@@ -29,7 +30,6 @@ import org.apache.fop.datatypes.SimplePercentBaseContext;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.CommonMarginBlock;
-import org.apache.fop.fo.properties.CommonMarginBlock;
import org.apache.fop.fo.properties.CommonTextDecoration;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
import org.apache.fop.fonts.Font;
@@ -46,11 +46,12 @@ public class TraitSetter {
/**
* Sets border and padding traits on areas.
- * @param area area to set the traits on
- * @param bpProps border and padding properties
+ *
+ * @param area area to set the traits on
+ * @param bpProps border and padding properties
* @param bNotFirst True if the area is not the first area
- * @param bNotLast True if the area is not the last area
- * @param context Property evaluation context
+ * @param bNotLast True if the area is not the last area
+ * @param context Property evaluation context
*/
public static void setBorderPaddingTraits(Area area,
CommonBorderPaddingBackground bpProps, boolean bNotFirst, boolean bNotLast,
@@ -74,27 +75,28 @@ public class TraitSetter {
}
addBorderTrait(area, bpProps, bNotFirst,
- CommonBorderPaddingBackground.START,
- BorderProps.SEPARATE, Trait.BORDER_START);
+ CommonBorderPaddingBackground.START,
+ BorderProps.SEPARATE, Trait.BORDER_START);
addBorderTrait(area, bpProps, bNotLast,
- CommonBorderPaddingBackground.END,
- BorderProps.SEPARATE, Trait.BORDER_END);
+ CommonBorderPaddingBackground.END,
+ BorderProps.SEPARATE, Trait.BORDER_END);
addBorderTrait(area, bpProps, false,
- CommonBorderPaddingBackground.BEFORE,
- BorderProps.SEPARATE, Trait.BORDER_BEFORE);
+ CommonBorderPaddingBackground.BEFORE,
+ BorderProps.SEPARATE, Trait.BORDER_BEFORE);
addBorderTrait(area, bpProps, false,
- CommonBorderPaddingBackground.AFTER,
- BorderProps.SEPARATE, Trait.BORDER_AFTER);
+ CommonBorderPaddingBackground.AFTER,
+ BorderProps.SEPARATE, Trait.BORDER_AFTER);
}
/**
* Sets border traits on an area.
- * @param area area to set the traits on
+ *
+ * @param area area to set the traits on
* @param bpProps border and padding properties
- * @param mode the border paint mode (see BorderProps)
+ * @param mode the border paint mode (see BorderProps)
*/
private static void addBorderTrait(Area area,
CommonBorderPaddingBackground bpProps,
@@ -103,9 +105,9 @@ public class TraitSetter {
int iBP = bpProps.getBorderWidth(iSide, bDiscard);
if (iBP > 0) {
area.addTrait(oTrait,
- new BorderProps(bpProps.getBorderStyle(iSide),
- iBP, bpProps.getBorderColor(iSide),
- mode));
+ new BorderProps(bpProps.getBorderStyle(iSide),
+ iBP, bpProps.getBorderColor(iSide),
+ mode));
}
}
@@ -119,7 +121,7 @@ public class TraitSetter {
* @deprecated Call the other addBorders() method and addPadding separately.
*/
public static void addBorders(Area area, CommonBorderPaddingBackground bordProps,
- PercentBaseContext context) {
+ PercentBaseContext context) {
BorderProps bps = getBorderProps(bordProps, CommonBorderPaddingBackground.BEFORE);
if (bps != null) {
area.addTrait(Trait.BORDER_BEFORE, bps);
@@ -397,9 +399,9 @@ public class TraitSetter {
int imageWidthMpt = back.getImageInfo().getSize().getWidthMpt();
int lengthBaseValue = width - imageWidthMpt;
SimplePercentBaseContext simplePercentBaseContext
- = new SimplePercentBaseContext(context,
- LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL,
- lengthBaseValue);
+ = new SimplePercentBaseContext(context,
+ LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL,
+ lengthBaseValue);
int horizontal = backProps.backgroundPositionHorizontal.getValue(
simplePercentBaseContext);
back.setHoriz(horizontal);
@@ -421,7 +423,7 @@ public class TraitSetter {
int imageHeightMpt = back.getImageInfo().getSize().getHeightMpt();
int lengthBaseValue = height - imageHeightMpt;
SimplePercentBaseContext simplePercentBaseContext
- = new SimplePercentBaseContext(context,
+ = new SimplePercentBaseContext(context,
LengthBase.IMAGE_BACKGROUND_POSITION_VERTICAL,
lengthBaseValue);
int vertical = backProps.backgroundPositionVertical.getValue(
@@ -459,8 +461,8 @@ public class TraitSetter {
}
int spaceStart = startIndent
- - bpProps.getBorderStartWidth(false)
- - bpProps.getPaddingStart(false, context);
+ - bpProps.getBorderStartWidth(false)
+ - bpProps.getPaddingStart(false, context);
if (spaceStart != 0) {
area.addTrait(Trait.SPACE_START, new Integer(spaceStart));
}
@@ -469,8 +471,8 @@ public class TraitSetter {
area.addTrait(Trait.END_INDENT, new Integer(endIndent));
}
int spaceEnd = endIndent
- - bpProps.getBorderEndWidth(false)
- - bpProps.getPaddingEnd(false, context);
+ - bpProps.getBorderEndWidth(false)
+ - bpProps.getPaddingEnd(false, context);
if (spaceEnd != 0) {
area.addTrait(Trait.SPACE_END, new Integer(spaceEnd));
}
@@ -504,14 +506,15 @@ public class TraitSetter {
public static int getEffectiveSpace(double adjust, MinOptMax space) {
if (space == null) {
return 0;
- }
- int sp = space.opt;
- if (adjust > 0) {
- sp = sp + (int)(adjust * (space.max - space.opt));
} else {
- sp = sp + (int)(adjust * (space.opt - space.min));
+ int spaceOpt = space.getOpt();
+ if (adjust > 0) {
+ spaceOpt += (int) (adjust * space.getStretch());
+ } else {
+ spaceOpt += (int) (adjust * space.getShrink());
+ }
+ return spaceOpt;
}
- return sp;
}
/**
@@ -521,16 +524,17 @@ public class TraitSetter {
* @param spaceBefore the space-before space specifier
* @param spaceAfter the space-after space specifier
*/
- public static void addSpaceBeforeAfter(Area area, double adjust,
- MinOptMax spaceBefore, MinOptMax spaceAfter) {
- int space;
- space = getEffectiveSpace(adjust, spaceBefore);
- if (space != 0) {
- area.addTrait(Trait.SPACE_BEFORE, new Integer(space));
- }
- space = getEffectiveSpace(adjust, spaceAfter);
- if (space != 0) {
- area.addTrait(Trait.SPACE_AFTER, new Integer(space));
+ public static void addSpaceBeforeAfter(Area area, double adjust, MinOptMax spaceBefore,
+ MinOptMax spaceAfter) {
+ addSpaceTrait(area, Trait.SPACE_BEFORE, spaceBefore, adjust);
+ addSpaceTrait(area, Trait.SPACE_AFTER, spaceAfter, adjust);
+ }
+
+ private static void addSpaceTrait(Area area, Integer spaceTrait,
+ MinOptMax space, double adjust) {
+ int effectiveSpace = getEffectiveSpace(adjust, space);
+ if (effectiveSpace != 0) {
+ area.addTrait(spaceTrait, new Integer(effectiveSpace));
}
}
@@ -540,7 +544,7 @@ public class TraitSetter {
* @param breakBefore the value for break-before
* @param breakAfter the value for break-after
*/
- public static void addBreaks(Area area, int breakBefore, int breakAfter) {
+ public static void addBreaks(Area area, int breakBefore, int breakAfter) {
/* Currently disabled as these traits are never used by the renderers
area.addTrait(Trait.BREAK_AFTER, new Integer(breakAfter));
area.addTrait(Trait.BREAK_BEFORE, new Integer(breakBefore));
@@ -593,7 +597,7 @@ public class TraitSetter {
area.addTrait(Trait.PTR, ptr);
}
}
-
+
/**
* Sets the producer's ID as a trait on the area. This can be used to track back the
* generating FO node.
diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
index dcd993487..a19680f51 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
@@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.TextArea;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fonts.Font;
@@ -67,14 +68,13 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
hyphIPD = fobj.getCommonHyphenation().getHyphIPD(font);
borderProps = fobj.getCommonBorderPaddingBackground();
setCommonBorderPaddingBackground(borderProps);
- org.apache.fop.area.inline.TextArea chArea = getCharacterInlineArea(fobj);
+ TextArea chArea = getCharacterInlineArea(fobj);
chArea.setBaselineOffset(font.getAscender());
setCurrentArea(chArea);
}
- private org.apache.fop.area.inline.TextArea getCharacterInlineArea(Character node) {
- org.apache.fop.area.inline.TextArea text
- = new org.apache.fop.area.inline.TextArea();
+ private TextArea getCharacterInlineArea(Character node) {
+ TextArea text = new TextArea();
char ch = node.getCharacter();
if (CharUtilities.isAnySpace(ch)) {
// add space unless it's zero-width:
@@ -103,9 +103,9 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
Character fobj = (Character)this.fobj;
- ipd = new MinOptMax(font.getCharWidth(fobj.getCharacter()));
+ ipd = MinOptMax.getInstance(font.getCharWidth(fobj.getCharacter()));
- curArea.setIPD(ipd.opt);
+ curArea.setIPD(ipd.getOpt());
curArea.setBPD(font.getAscender() - font.getDescender());
TraitSetter.addFontTraits(curArea, font);
@@ -126,16 +126,16 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);
// node is a fo:Character
- if (letterSpaceIPD.min == letterSpaceIPD.max) {
+ if (letterSpaceIPD.isStiff()) {
// constant letter space, only return a box
- seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
+ seq.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), areaInfo.alignmentContext,
notifyPos(new LeafPosition(this, 0)), false));
} else {
// adjustable letter space, return a sequence of elements;
// at the moment the character is supposed to have no letter spaces,
// but returning this sequence allows us to change only one element
// if addALetterSpaceTo() is called
- seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
+ seq.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), areaInfo.alignmentContext,
notifyPos(new LeafPosition(this, 0)), false));
seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
new LeafPosition(this, -1), true));
@@ -154,9 +154,8 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
}
/** {@inheritDoc} */
- public void getWordChars(StringBuffer sbChars, Position bp) {
- sbChars.append
- (((org.apache.fop.area.inline.TextArea) curArea).getText());
+ public String getWordChars(Position pos) {
+ return ((TextArea) curArea).getText();
}
/** {@inheritDoc} */
@@ -189,10 +188,9 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
addKnuthElementsForBorderPaddingStart(returnList);
- if (letterSpaceIPD.min == letterSpaceIPD.max
- || areaInfo.iLScount == 0) {
+ if (letterSpaceIPD.isStiff() || areaInfo.iLScount == 0) {
// constant letter space, or no letter space
- returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt,
+ returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(),
areaInfo.alignmentContext,
notifyPos(new LeafPosition(this, 0)), false));
if (areaInfo.bHyphenated) {
@@ -202,24 +200,17 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
}
} else {
// adjustable letter space
- returnList.add
- (new KnuthInlineBox(areaInfo.ipdArea.opt
- - areaInfo.iLScount * letterSpaceIPD.opt,
- areaInfo.alignmentContext,
- notifyPos(new LeafPosition(this, 0)), false));
+ returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt()
+ - areaInfo.iLScount * letterSpaceIPD.getOpt(), areaInfo.alignmentContext,
+ notifyPos(new LeafPosition(this, 0)), false));
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
- new LeafPosition(this, -1), true));
- returnList.add
- (new KnuthGlue(areaInfo.iLScount * letterSpaceIPD.opt,
- areaInfo.iLScount * letterSpaceIPD.max - letterSpaceIPD.opt,
- areaInfo.iLScount * letterSpaceIPD.opt - letterSpaceIPD.min,
- new LeafPosition(this, -1), true));
- returnList.add(new KnuthInlineBox(0, null,
- notifyPos(new LeafPosition(this, -1)), true));
+ new LeafPosition(this, -1), true));
+ returnList.add(new KnuthGlue(letterSpaceIPD.mult(areaInfo.iLScount),
+ new LeafPosition(this, -1), true));
+ returnList.add(new KnuthInlineBox(0, null, notifyPos(new LeafPosition(this, -1)), true));
if (areaInfo.bHyphenated) {
- returnList.add
- (new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true,
- new LeafPosition(this, -1), false));
+ returnList.add(new KnuthPenalty(hyphIPD, KnuthPenalty.FLAGGED_PENALTY, true,
+ new LeafPosition(this, -1), false));
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index 4680f642e..d0dcc2bb8 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -296,7 +296,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
log.warn(this.getClass().getName() + " should not receive a call to removeWordSpace(list)");
}
- public void getWordChars(StringBuffer sbChars, Position pos) {
+ public String getWordChars(Position pos) {
+ return "";
}
public void hyphenate(Position pos, HyphContext hc) {
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
index 6e0c34a82..26f8e3b97 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
@@ -19,6 +19,7 @@
package org.apache.fop.layoutmgr.inline;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -144,7 +145,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
padding += borderProps.getPadding(CommonBorderPaddingBackground.AFTER, false, this);
padding += borderProps.getBorderWidth(CommonBorderPaddingBackground.AFTER, false);
}
- extraBPD = new MinOptMax(padding);
+ extraBPD = MinOptMax.getInstance(padding);
}
@@ -161,7 +162,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
borderAndPadding
+= borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast);
}
- return new MinOptMax(borderAndPadding);
+ return MinOptMax.getInstance(borderAndPadding);
}
@@ -325,16 +326,20 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
KnuthSequence sequence = (KnuthSequence) seqIter.next();
sequence.wrapPositions(this);
}
+ int insertionStartIndex = 0;
if (lastSequence != null && lastSequence.appendSequenceOrClose
((KnuthSequence) returnedList.get(0))) {
- returnedList.remove(0);
+ insertionStartIndex = 1;
}
// add border and padding to the first complete sequence of this LM
if (!borderAdded && !returnedList.isEmpty()) {
addKnuthElementsForBorderPaddingStart((KnuthSequence) returnedList.get(0));
borderAdded = true;
}
- returnList.addAll(returnedList);
+ for (Iterator iter = returnedList.listIterator(insertionStartIndex);
+ iter.hasNext();) {
+ returnList.add(iter.next());
+ }
} else { // A block LM
BlockKnuthSequence sequence = new BlockKnuthSequence(returnedList);
sequence.wrapPositions(this);
@@ -488,8 +493,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
boolean isLast = (getContext().isLastArea() && prevLM == lastChildLM);
if (hasTrailingFence(isLast)) {
- addSpace(getCurrentArea(),
- getContext().getTrailingSpace().resolve(false),
+ addSpace(getCurrentArea(), getContext().getTrailingSpace().resolve(false),
getContext().getSpaceAdjust());
context.setTrailingSpace(new SpaceSpecifier(false));
} else {
@@ -504,7 +508,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
// Not sure if lastPos can legally be null or if that masks a different problem.
// But it seems to fix bug 38053.
setTraits(areaCreated, lastPos == null || !isLast(lastPos));
- parentLM.addChildArea(getCurrentArea());
+ parentLayoutManager.addChildArea(getCurrentArea());
addMarkersToPage(
false,
@@ -520,8 +524,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
public void addChildArea(Area childArea) {
Area parent = getCurrentArea();
if (getContext().resolveLeadingSpace()) {
- addSpace(parent,
- getContext().getLeadingSpace().resolve(false),
+ addSpace(parent, getContext().getLeadingSpace().resolve(false),
getContext().getSpaceAdjust());
}
parent.addChildArea(childArea);
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java
index b080f926b..525f0407d 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java
@@ -48,20 +48,19 @@ public interface InlineLevelLayoutManager extends LayoutManager {
void removeWordSpace(List oldList);
/**
- * Get the word chars corresponding to the given position
+ * Get the word chars corresponding to the given position.
*
- * @param sbChars the StringBuffer used to append word chars
- * @param pos the Position referring to the needed word chars
+ * @param pos the position referring to the needed word chars.
*/
- void getWordChars(StringBuffer sbChars, Position pos);
+ String getWordChars(Position pos);
/**
* Tell the LM to hyphenate a word
*
* @param pos the Position referring to the word
- * @param hc the HyphContext storing hyphenation information
+ * @param hyphContext the HyphContext storing hyphenation information
*/
- void hyphenate(Position pos, HyphContext hc);
+ void hyphenate(Position pos, HyphContext hyphContext);
/**
* Tell the LM to apply the changes due to hyphenation
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
index 65e59554f..375afb82f 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
@@ -80,7 +80,7 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
*/
protected InlineStackingLayoutManager(FObj node) {
super(node);
- extraBPD = new MinOptMax(0);
+ extraBPD = MinOptMax.ZERO;
}
/**
@@ -100,7 +100,7 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
* @return the extra IPD as a MinOptMax spec
*/
protected MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) {
- return new MinOptMax(0);
+ return MinOptMax.ZERO;
}
@@ -179,23 +179,21 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
}
/**
- * Adds a space to the area
+ * Adds a space to the area.
+ *
* @param parentArea the area to which to add the space
* @param spaceRange the space range specifier
- * @param dSpaceAdjust the factor by which to stretch or shrink the space
+ * @param spaceAdjust the factor by which to stretch or shrink the space
*/
- protected void addSpace(Area parentArea, MinOptMax spaceRange,
- double dSpaceAdjust) {
+ protected void addSpace(Area parentArea, MinOptMax spaceRange, double spaceAdjust) {
if (spaceRange != null) {
- int iAdjust = spaceRange.opt;
- if (dSpaceAdjust > 0.0) {
+ int iAdjust = spaceRange.getOpt();
+ if (spaceAdjust > 0.0) {
// Stretch by factor
- iAdjust += (int) ((double) (spaceRange.max
- - spaceRange.opt) * dSpaceAdjust);
- } else if (dSpaceAdjust < 0.0) {
+ iAdjust += (int) (spaceRange.getStretch() * spaceAdjust);
+ } else if (spaceAdjust < 0.0) {
// Shrink by factor
- iAdjust += (int) ((double) (spaceRange.opt
- - spaceRange.min) * dSpaceAdjust);
+ iAdjust += (int) (spaceRange.getShrink() * spaceAdjust);
}
if (iAdjust != 0) {
//getLogger().debug("Add leading space: " + iAdjust);
@@ -257,10 +255,9 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
}
/** {@inheritDoc} */
- public void getWordChars(StringBuffer sbChars, Position pos) {
+ public String getWordChars(Position pos) {
Position newPos = pos.getPosition();
- ((InlineLevelLayoutManager)
- newPos.getLM()).getWordChars(sbChars, newPos);
+ return ((InlineLevelLayoutManager) newPos.getLM()).getWordChars(newPos);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java b/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
index 6c8c7354b..7b08a67db 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
@@ -19,7 +19,6 @@
package org.apache.fop.layoutmgr.inline;
-import org.apache.fop.layoutmgr.inline.AlignmentContext;
import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.Position;
@@ -32,13 +31,13 @@ public class KnuthInlineBox extends KnuthBox {
/**
* Create a new KnuthBox.
*
- * @param w the width of this box
+ * @param width the width of this box
* @param alignmentContext the alignmentContext for this box
- * @param pos the Position stored in this box
- * @param bAux is this box auxiliary?
+ * @param pos the Position stored in this box
+ * @param auxiliary is this box auxiliary?
*/
- public KnuthInlineBox(int w, AlignmentContext alignmentContext, Position pos, boolean bAux) {
- super(w, pos, bAux);
+ public KnuthInlineBox(int width, AlignmentContext alignmentContext, Position pos, boolean auxiliary) {
+ super(width, pos, auxiliary);
this.alignmentContext = alignmentContext;
}
@@ -69,11 +68,4 @@ public class KnuthInlineBox extends KnuthBox {
public boolean isAnchor() {
return (footnoteBodyLM != null);
}
-
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
- return sb.toString();
- }
-} \ No newline at end of file
+}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
index fe82245b9..c5f38134b 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
@@ -19,6 +19,7 @@
package org.apache.fop.layoutmgr.inline;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -109,7 +110,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
- borderPaddingWidth;
int max = fobj.getLeaderLength().getMaximum(this).getLength().getValue(this)
- borderPaddingWidth;
- return new MinOptMax(min, opt, max);
+ return MinOptMax.getInstance(min, opt, max);
}
private InlineArea getLeaderInlineArea(LayoutContext context) {
@@ -226,7 +227,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
KnuthPossPosIter contentIter = new KnuthPossPosIter(contentList, 0, contentList.size());
clm.addAreas(contentIter, context);
- parentLM.addChildArea(curArea);
+ parentLayoutManager.addChildArea(curArea);
while (posIter.hasNext()) {
posIter.next();
@@ -235,8 +236,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
}
/** {@inheritDoc} */
- public List getNextKnuthElements(LayoutContext context,
- int alignment) {
+ public List getNextKnuthElements(LayoutContext context, int alignment) {
MinOptMax ipd;
curArea = get(context);
KnuthSequence seq = new InlineKnuthSequence();
@@ -256,45 +256,34 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
ipd = getAllocationIPD(context.getRefIPD());
if (fobj.getLeaderPattern() == EN_USECONTENT && curArea instanceof FilledArea) {
// If we have user supplied content make it fit if we can
- int unitWidth = ((FilledArea)curArea).getUnitWidth();
- if (ipd.opt < unitWidth && ipd.max >= unitWidth) {
- ipd.opt = unitWidth;
+ int unitWidth = ((FilledArea) curArea).getUnitWidth();
+ if (ipd.getOpt() < unitWidth && unitWidth <= ipd.getMax()) {
+ ipd = MinOptMax.getInstance(ipd.getMin(), unitWidth, ipd.getMax());
}
}
// create the AreaInfo object to store the computed values
areaInfo = new AreaInfo((short) 0, ipd, false, context.getAlignmentContext());
- curArea.setAdjustingInfo(ipd.max - ipd.opt, ipd.opt - ipd.min, 0);
+ curArea.setAdjustingInfo(ipd.getStretch(), ipd.getShrink(), 0);
addKnuthElementsForBorderPaddingStart(seq);
// node is a fo:Leader
- seq.add(new KnuthInlineBox(0, alignmentContext,
- new LeafPosition(this, -1), true));
+ seq.add(new KnuthInlineBox(0, alignmentContext, new LeafPosition(this, -1), true));
seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
- new LeafPosition(this, -1), true));
+ new LeafPosition(this, -1), true));
if (alignment == EN_JUSTIFY || alignment == 0) {
- seq.add
- (new KnuthGlue(areaInfo.ipdArea.opt,
- areaInfo.ipdArea.max - areaInfo.ipdArea.opt,
- areaInfo.ipdArea.opt - areaInfo.ipdArea.min,
- new LeafPosition(this, 0), false));
+ seq.add(new KnuthGlue(areaInfo.ipdArea, new LeafPosition(this, 0), false));
} else {
- seq.add
- (new KnuthGlue(areaInfo.ipdArea.opt,
- 0,
- 0,
- new LeafPosition(this, 0), false));
+ seq.add(new KnuthGlue(areaInfo.ipdArea.getOpt(), 0, 0,
+ new LeafPosition(this, 0), false));
}
- seq.add(new KnuthInlineBox(0, alignmentContext,
- new LeafPosition(this, -1), true));
+ seq.add(new KnuthInlineBox(0, alignmentContext, new LeafPosition(this, -1), true));
addKnuthElementsForBorderPaddingEnd(seq);
- LinkedList returnList = new LinkedList();
- returnList.add(seq);
setFinished(true);
- return returnList;
+ return Collections.singletonList(seq);
}
/** {@inheritDoc} */
@@ -310,8 +299,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
}
/** {@inheritDoc} */
- public List getChangedKnuthElements(List oldList,
- int alignment) {
+ public List getChangedKnuthElements(List oldList, int alignment) {
if (isFinished()) {
return null;
}
@@ -325,17 +313,10 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager {
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
new LeafPosition(this, -1), true));
if (alignment == EN_JUSTIFY || alignment == 0) {
- returnList.add
- (new KnuthGlue(areaInfo.ipdArea.opt,
- areaInfo.ipdArea.max - areaInfo.ipdArea.opt,
- areaInfo.ipdArea.opt - areaInfo.ipdArea.min,
- new LeafPosition(this, 0), false));
+ returnList.add(new KnuthGlue(areaInfo.ipdArea, new LeafPosition(this, 0), false));
} else {
- returnList.add
- (new KnuthGlue(areaInfo.ipdArea.opt,
- 0,
- 0,
- new LeafPosition(this, 0), false));
+ returnList.add(new KnuthGlue(areaInfo.ipdArea.getOpt(), 0, 0,
+ new LeafPosition(this, 0), false));
}
returnList.add(new KnuthInlineBox(0, areaInfo.alignmentContext,
new LeafPosition(this, -1), true));
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
index ac501abb7..e74b51d96 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr.inline;
import java.util.LinkedList;
import java.util.List;
+import java.util.Collections;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -163,7 +164,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
* @return the min/opt/max ipd of the inline area
*/
protected MinOptMax getAllocationIPD(int refIPD) {
- return new MinOptMax(curArea.getIPD());
+ return MinOptMax.getInstance(curArea.getIPD());
}
/**
@@ -186,7 +187,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
false, false, this);
TraitSetter.addBackground(area, commonBorderPaddingBackground, this);
}
- parentLM.addChildArea(area);
+ parentLayoutManager.addChildArea(area);
}
while (posIter.hasNext()) {
@@ -236,16 +237,14 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
*/
protected void widthAdjustArea(InlineArea area, LayoutContext context) {
double dAdjust = context.getIPDAdjust();
- int width = areaInfo.ipdArea.opt;
+ int adjustment = 0;
if (dAdjust < 0) {
- width = (int) (width + dAdjust * (areaInfo.ipdArea.opt
- - areaInfo.ipdArea.min));
+ adjustment += (int) (dAdjust * areaInfo.ipdArea.getShrink());
} else if (dAdjust > 0) {
- width = (int) (width + dAdjust * (areaInfo.ipdArea.max
- - areaInfo.ipdArea.opt));
+ adjustment += (int) (dAdjust * areaInfo.ipdArea.getStretch());
}
- area.setIPD(width);
- area.setAdjustment(width - areaInfo.ipdArea.opt);
+ area.setIPD(areaInfo.ipdArea.getOpt() + adjustment);
+ area.setAdjustment(adjustment);
}
/** {@inheritDoc} */
@@ -270,16 +269,13 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
addKnuthElementsForBorderPaddingStart(seq);
- seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, alignmentContext,
+ seq.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), alignmentContext,
notifyPos(new LeafPosition(this, 0)), false));
addKnuthElementsForBorderPaddingEnd(seq);
- LinkedList returnList = new LinkedList();
-
- returnList.add(seq);
setFinished(true);
- return returnList;
+ return Collections.singletonList(seq);
}
/** {@inheritDoc} */
@@ -299,11 +295,12 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
}
/** {@inheritDoc} */
- public void getWordChars(StringBuffer sbChars, Position pos) {
+ public String getWordChars(Position pos) {
+ return "";
}
/** {@inheritDoc} */
- public void hyphenate(Position pos, HyphContext hc) {
+ public void hyphenate(Position pos, HyphContext hyphContext) {
}
/** {@inheritDoc} */
@@ -325,7 +322,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager
// fobj is a fo:ExternalGraphic, fo:InstreamForeignObject,
// fo:PageNumber or fo:PageNumberCitation
- returnList.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
+ returnList.add(new KnuthInlineBox(areaInfo.ipdArea.getOpt(), areaInfo.alignmentContext,
notifyPos(new LeafPosition(this, 0)), true));
addKnuthElementsForBorderPaddingEnd(returnList);
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 0b95ef859..0ece70cac 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -43,6 +43,7 @@ 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.Adjustment;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
@@ -235,11 +236,10 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// set the minimum amount of empty space at the end of the
// last line
if (textAlignment == EN_CENTER) {
- lineFiller = new MinOptMax(lastLineEndIndent);
+ lineFiller = MinOptMax.getInstance(lastLineEndIndent);
} else {
- lineFiller = new MinOptMax(lastLineEndIndent,
- lastLineEndIndent,
- layoutManager.ipd);
+ lineFiller = MinOptMax.getInstance(lastLineEndIndent, lastLineEndIndent,
+ layoutManager.ipd);
}
// add auxiliary elements at the beginning of the paragraph
@@ -272,7 +272,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
&& textAlignmentLast != EN_JUSTIFY) {
this.add(new KnuthGlue(0, 3 * DEFAULT_SPACE_WIDTH, 0,
null, false));
- this.add(new KnuthPenalty(lineFiller.opt, -KnuthElement.INFINITE,
+ this.add(new KnuthPenalty(lineFiller.getOpt(), -KnuthElement.INFINITE,
false, null, false));
ignoreAtEnd = 2;
} else if (textAlignmentLast != EN_JUSTIFY) {
@@ -282,14 +282,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager
this.add(new KnuthPenalty(0, KnuthElement.INFINITE,
false, null, false));
this.add(new KnuthGlue(0,
- lineFiller.max - lineFiller.opt,
- lineFiller.opt - lineFiller.min, null, false));
- this.add(new KnuthPenalty(lineFiller.opt, -KnuthElement.INFINITE,
+ lineFiller.getStretch(),
+ lineFiller.getShrink(), null, false));
+ this.add(new KnuthPenalty(lineFiller.getOpt(), -KnuthElement.INFINITE,
false, null, false));
ignoreAtEnd = 3;
} else {
// add only the element representing the forced break
- this.add(new KnuthPenalty(lineFiller.opt, -KnuthElement.INFINITE,
+ this.add(new KnuthPenalty(lineFiller.getOpt(), -KnuthElement.INFINITE,
false, null, false));
ignoreAtEnd = 1;
}
@@ -393,7 +393,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
(bestActiveNode.line > 1 ? bestActiveNode.previous.position + 1 : 0),
bestActiveNode.position,
bestActiveNode.availableShrink - (addedPositions > 0
- ? 0 : ((Paragraph)par).lineFiller.opt - ((Paragraph)par).lineFiller.min),
+ ? 0 : ((Paragraph) par).lineFiller.getShrink()),
bestActiveNode.availableStretch,
difference, ratio, indent), activePossibility);
addedPositions++;
@@ -784,7 +784,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
int iBPcount = 0;
LineBreakingAlgorithm alg = new LineBreakingAlgorithm(alignment,
textAlignment, textAlignmentLast,
- textIndent.getValue(this), currPar.lineFiller.opt,
+ textIndent.getValue(this), currPar.lineFiller.getOpt(),
lineHeight.getValue(this), lead, follow,
(knuthParagraphs.indexOf(currPar) == 0),
hyphenationLadderCount.getEnum() == EN_NO_LIMIT
@@ -1057,12 +1057,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager
breaker.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, elementPosition, false));
breaker.add(new KnuthGlue(0, -nConditionalOptionalLines * constantLineHeight,
-nConditionalEliminableLines * constantLineHeight,
- LINE_NUMBER_ADJUSTMENT, elementPosition, false));
+ Adjustment.LINE_NUMBER_ADJUSTMENT, elementPosition, false));
breaker.add(new KnuthPenalty(nConditionalOptionalLines * constantLineHeight,
0, false, elementPosition, false));
breaker.add(new KnuthGlue(0, nConditionalOptionalLines * constantLineHeight,
nConditionalEliminableLines * constantLineHeight,
- LINE_NUMBER_ADJUSTMENT, elementPosition, false));
+ Adjustment.LINE_NUMBER_ADJUSTMENT, elementPosition, false));
} else if (nLastLines != 0) {
breaker.add(new KnuthPenalty(0, 0, false, elementPosition, false));
}
@@ -1083,7 +1083,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
list.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, elementPosition, false));
list.add(new KnuthGlue(0, nConditionalOptionalLines * constantLineHeight,
nConditionalEliminableLines * constantLineHeight,
- LINE_NUMBER_ADJUSTMENT, elementPosition, false));
+ Adjustment.LINE_NUMBER_ADJUSTMENT, elementPosition, false));
list.add(new KnuthBox(0, elementPosition,
(nLastLines == 0 ? true : false)));
}
@@ -1094,7 +1094,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
list.add(new KnuthBox(0, elementPosition, false));
list.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, elementPosition, false));
list.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
- LINE_NUMBER_ADJUSTMENT, elementPosition, false));
+ Adjustment.LINE_NUMBER_ADJUSTMENT, elementPosition, false));
list.add(new KnuthBox(0, elementPosition, false));
}
@@ -1104,7 +1104,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
list.add(new KnuthBox(1 * constantLineHeight, elementPosition, false));
list.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, elementPosition, false));
list.add(new KnuthGlue(0, 0, 1 * constantLineHeight,
- LINE_NUMBER_ADJUSTMENT, elementPosition, false));
+ Adjustment.LINE_NUMBER_ADJUSTMENT, elementPosition, false));
list.add(new KnuthBox(0, elementPosition, false));
}
@@ -1200,7 +1200,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
llPoss = (LineLayoutPossibilities)lineLayoutsList.get(p);
//log.debug("demerits of the chosen layout: " + llPoss.getChosenDemerits());
for (int i = 0; i < llPoss.getChosenLineCount(); i++) {
- if (!((BlockLevelLayoutManager) parentLM).mustKeepTogether()
+ if (!((BlockLevelLayoutManager) parentLayoutManager).mustKeepTogether()
&& i >= fobj.getOrphans()
&& i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
// null penalty allowing a page break between lines
@@ -1213,21 +1213,19 @@ public class LineLayoutManager extends InlineStackingLayoutManager
//log.debug("linewidth= " + lbp.lineWidth + " difference= " + lbp.difference + " indent= " + lbp.startIndent);
MinOptMax contentIPD;
if (alignment == EN_JUSTIFY) {
- contentIPD = new MinOptMax(
+ contentIPD = MinOptMax.getInstance(
lbp.lineWidth - lbp.difference - lbp.availableShrink,
lbp.lineWidth - lbp.difference,
lbp.lineWidth - lbp.difference + lbp.availableStretch);
} else if (alignment == EN_CENTER) {
- contentIPD = new MinOptMax(lbp.lineWidth - 2 * lbp.startIndent);
+ contentIPD = MinOptMax.getInstance(lbp.lineWidth - 2 * lbp.startIndent);
} else if (alignment == EN_END) {
- contentIPD = new MinOptMax(lbp.lineWidth - lbp.startIndent);
+ contentIPD = MinOptMax.getInstance(lbp.lineWidth - lbp.startIndent);
} else {
- contentIPD = new MinOptMax(lbp.lineWidth - lbp.difference + lbp.startIndent);
+ contentIPD = MinOptMax.getInstance(lbp.lineWidth - lbp.difference + lbp.startIndent);
}
- returnList.add(new KnuthBlockBox(lbp.lineHeight,
- contentIPD,
- (lbp.ipdAdjust != 0
- ? lbp.lineWidth - lbp.difference : 0),
+ returnList.add(new KnuthBlockBox(lbp.lineHeight, contentIPD, (lbp.ipdAdjust != 0
+ ? lbp.lineWidth - lbp.difference : 0),
lbp, false));
}
}
@@ -1277,7 +1275,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
boxCount = 1;
auxCount = 0;
sbChars = new StringBuffer();
- currLM.getWordChars(sbChars, firstElement.getPosition());
+ sbChars.append(currLM.getWordChars(firstElement.getPosition()));
// look if next elements are boxes too
while (currParIterator.hasNext()) {
nextElement = (KnuthElement) currParIterator.next();
@@ -1289,7 +1287,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
// append text to recreate the whole word
boxCount++;
- currLM.getWordChars(sbChars, nextElement.getPosition());
+ sbChars.append(currLM.getWordChars(nextElement.getPosition()));
} else if (!nextElement.isAuxiliary()) {
// a non-auxiliary non-box KnuthElement: stop
// go back to the last box or auxiliary element
@@ -1583,7 +1581,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter());
}
lineArea.finalise();
- parentLM.addChildArea(lineArea);
+ parentLayoutManager.addChildArea(lineArea);
}
/**
@@ -1633,7 +1631,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
blocklc.setTrailingSpace(new SpaceSpecifier(false));
}
lineArea.updateExtentsFromChildren();
- parentLM.addChildArea(lineArea);
+ parentLayoutManager.addChildArea(lineArea);
}
/**
@@ -1644,9 +1642,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
if (childArea instanceof InlineArea) {
Area parent = getCurrentArea();
if (getContext().resolveLeadingSpace()) {
- addSpace(parent,
- getContext().getLeadingSpace().resolve(false),
- getContext().getSpaceAdjust());
+ addSpace(parent, getContext().getLeadingSpace().resolve(false),
+ getContext().getSpaceAdjust());
}
parent.addChildArea(childArea);
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
index d33f2cca1..a38e3e2d8 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
@@ -46,7 +46,7 @@ public class PageNumberCitationLastLayoutManager extends AbstractPageNumberCitat
/** {@inheritDoc} */
public InlineArea get(LayoutContext context) {
- curArea = getPageNumberCitationLastInlineArea(parentLM);
+ curArea = getPageNumberCitationLastInlineArea(parentLayoutManager);
return curArea;
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
index 5cae07207..d8cfe6cda 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
@@ -116,7 +116,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager {
// update the ipd of the area
area.handleIPDVariation(getStringWidth(area.getText()) - area.getIPD());
// update the width stored in the AreaInfo object
- areaInfo.ipdArea = new MinOptMax(area.getIPD());
+ areaInfo.ipdArea = MinOptMax.getInstance(area.getIPD());
}
/**
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index f793bb3bb..43e8c5a31 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -19,6 +19,7 @@
package org.apache.fop.layoutmgr.inline;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -59,6 +60,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
//TODO: remove all final modifiers at local variables
+ // static final int SOFT_HYPHEN_PENALTY = KnuthPenalty.FLAGGED_PENALTY / 10;
+ private static final int SOFT_HYPHEN_PENALTY = 1;
+
/**
* Store information about each potential text area.
* Index of character which ends the area, IPD of area, including
@@ -66,25 +70,27 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* Number of word-spaces?
*/
private class AreaInfo {
+
private final int startIndex;
private final int breakIndex;
private final int wordSpaceCount;
private int letterSpaceCount;
- private final MinOptMax areaIPD;
+ private MinOptMax areaIPD;
private final boolean isHyphenated;
private final boolean isSpace;
private boolean breakOppAfter;
private final Font font;
AreaInfo(final int startIndex,
- final int breakIndex,
- final int wordSpaceCount,
- final int letterSpaceCount,
- final MinOptMax areaIPD,
- final boolean isHyphenated,
- final boolean isSpace,
- final boolean breakOppAfter,
- final Font font) {
+ final int breakIndex,
+ final int wordSpaceCount,
+ final int letterSpaceCount,
+ final MinOptMax areaIPD,
+ final boolean isHyphenated,
+ final boolean isSpace,
+ final boolean breakOppAfter,
+ final Font font) {
+ assert startIndex <= breakIndex;
this.startIndex = startIndex;
this.breakIndex = breakIndex;
this.wordSpaceCount = wordSpaceCount;
@@ -96,28 +102,38 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
this.font = font;
}
- public String toString() {
- return "[ lscnt=" + this.letterSpaceCount
- + ", wscnt=" + this.wordSpaceCount
- + ", ipd=" + this.areaIPD.toString()
- + ", sidx=" + this.startIndex
- + ", bidx=" + this.breakIndex
- + ", hyph=" + this.isHyphenated
- + ", space=" + this.isSpace
- + ", font=" + this.font
- + "]";
+ private int getCharLength() {
+ return breakIndex - startIndex;
+ }
+
+ private void addToAreaIPD(MinOptMax idp) {
+ areaIPD = areaIPD.plus(idp);
}
+ public String toString() {
+ return "AreaInfo["
+ + "letterSpaceCount = " + letterSpaceCount
+ + ", wordSpaceCount = " + wordSpaceCount
+ + ", areaIPD = " + areaIPD
+ + ", startIndex = " + startIndex
+ + ", breakIndex = " + breakIndex
+ + ", isHyphenated = " + isHyphenated
+ + ", isSpace = " + isSpace
+ + ", font = " + font
+ + "]";
+ }
}
- // this class stores information about changes in vecAreaInfo
- // which are not yet applied
+ /**
+ * this class stores information about changes in vecAreaInfo which are not yet applied
+ */
private final class PendingChange {
- private final AreaInfo ai;
+
+ private final AreaInfo areaInfo;
private final int index;
- private PendingChange(final AreaInfo ai, final int index) {
- this.ai = ai;
+ private PendingChange(final AreaInfo areaInfo, final int index) {
+ this.areaInfo = areaInfo;
this.index = index;
}
}
@@ -128,14 +144,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private static final Log LOG = LogFactory.getLog(TextLayoutManager.class);
// Hold all possible breaks for the text in this LM's FO.
- private final List vecAreaInfo;
+ private final List areaInfos;
/** Non-space characters on which we can end a line. */
private static final String BREAK_CHARS = "-/";
- /** Used to reduce instantiation of MinOptMax with zero length. Do not modify! */
- private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0);
-
private final FOText foText;
/**
@@ -155,18 +168,23 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private MinOptMax letterSpaceIPD;
/** size of the hyphen character glyph in current font */
private int hyphIPD;
- /** 1/1 of word-spacing value */
- private SpaceVal ws;
private boolean hasChanged = false;
private int returnedIndex = 0;
private int thisStart = 0;
private int tempStart = 0;
- private List changeList = null;
+ private List changeList = new LinkedList();
private AlignmentContext alignmentContext = null;
+ /**
+ * The width to be reserved for border and padding at the start of the line.
+ */
private int lineStartBAP = 0;
+
+ /**
+ * The width to be reserved for border and padding at the end of the line.
+ */
private int lineEndBAP = 0;
private boolean keepTogether;
@@ -178,49 +196,37 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
*
* @param node The FOText object to be rendered
*/
- public TextLayoutManager(final FOText node) {
- super();
- this.foText = node;
-
- this.letterAdjustArray = new MinOptMax[node.length() + 1];
-
- this.vecAreaInfo = new java.util.ArrayList();
+ public TextLayoutManager(FOText node) {
+ foText = node;
+ letterAdjustArray = new MinOptMax[node.length() + 1];
+ areaInfos = new ArrayList();
}
- private KnuthPenalty makeZeroWidthPenalty(final int penaltyValue) {
- return new KnuthPenalty(
- 0,
- penaltyValue,
- false,
- this.auxiliaryPosition,
- true);
+ private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
+ return new KnuthPenalty(0, penaltyValue, false, auxiliaryPosition, true);
}
private KnuthBox makeAuxiliaryZeroWidthBox() {
- return new KnuthInlineBox(
- 0,
- null,
- this.notifyPos(new LeafPosition(this, -1)),
- true);
+ return new KnuthInlineBox(0, null, notifyPos(new LeafPosition(this, -1)), true);
}
/** {@inheritDoc} */
public void initialize() {
- this.foText.resetBuffer();
+ foText.resetBuffer();
- this.spaceFont = FontSelector.selectFontForCharacterInText(' ', this.foText, this);
+ spaceFont = FontSelector.selectFontForCharacterInText(' ', foText, this);
- // With CID fonts, space isn't neccesary currentFontState.width(32)
- this.spaceCharIPD = this.spaceFont.getCharWidth(' ');
- // Use hyphenationChar property
+ // With CID fonts, space isn't necessary currentFontState.width(32)
+ spaceCharIPD = spaceFont.getCharWidth(' ');
+ // Use hyphenationChar property
// TODO: Use hyphen based on actual font used!
- this.hyphIPD = this.foText.getCommonHyphenation().getHyphIPD(this.spaceFont);
+ hyphIPD = foText.getCommonHyphenation().getHyphIPD(spaceFont);
- final SpaceVal ls = SpaceVal.makeLetterSpacing(this.foText.getLetterSpacing());
-
- this.ws = SpaceVal.makeWordSpacing(this.foText.getWordSpacing(), ls, this.spaceFont);
+ SpaceVal letterSpacing = SpaceVal.makeLetterSpacing(foText.getLetterSpacing());
+ SpaceVal wordSpacing = SpaceVal.makeWordSpacing(foText.getWordSpacing(), letterSpacing,
+ spaceFont);
// letter space applies only to consecutive non-space characters,
// while word space applies to space characters;
@@ -233,12 +239,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// set letter space and word space dimension;
// the default value "normal" was converted into a MinOptMax value
// in the SpaceVal.makeWordSpacing() method
- this.letterSpaceIPD = ls.getSpace();
- this.wordSpaceIPD = MinOptMax.add(new MinOptMax(this.spaceCharIPD), this.ws.getSpace());
-
- this.keepTogether = this.foText.getKeepTogether().getWithinLine()
- .getEnum() == Constants.EN_ALWAYS;
-
+ letterSpaceIPD = letterSpacing.getSpace();
+ wordSpaceIPD = MinOptMax.getInstance(spaceCharIPD).plus(wordSpacing.getSpace());
+ keepTogether = foText.getKeepTogether().getWithinLine().getEnum() == Constants.EN_ALWAYS;
}
/**
@@ -254,111 +257,103 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public void addAreas(final PositionIterator posIter, final LayoutContext context) {
// Add word areas
- AreaInfo ai;
+ AreaInfo areaInfo;
int wordSpaceCount = 0;
int letterSpaceCount = 0;
int firstAreaInfoIndex = -1;
int lastAreaInfoIndex = 0;
- MinOptMax realWidth = new MinOptMax(0);
+ MinOptMax realWidth = MinOptMax.ZERO;
/* On first area created, add any leading space.
* Calculate word-space stretch value.
*/
- AreaInfo lastAi = null;
+ AreaInfo lastAreaInfo = null;
while (posIter.hasNext()) {
final LeafPosition tbpNext = (LeafPosition) posIter.next();
if (tbpNext == null) {
continue; //Ignore elements without Positions
}
if (tbpNext.getLeafPos() != -1) {
- ai = (AreaInfo) this.vecAreaInfo.get(tbpNext.getLeafPos());
- if (lastAi == null || ai.font != lastAi.font) {
- if (lastAi != null) {
- this.addAreaInfoAreas(lastAi, wordSpaceCount,
+ areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos());
+ if (lastAreaInfo == null || areaInfo.font != lastAreaInfo.font) {
+ if (lastAreaInfo != null) {
+ addAreaInfoAreas(lastAreaInfo, wordSpaceCount,
letterSpaceCount, firstAreaInfoIndex,
lastAreaInfoIndex, realWidth, context);
}
firstAreaInfoIndex = tbpNext.getLeafPos();
wordSpaceCount = 0;
letterSpaceCount = 0;
- realWidth = new MinOptMax(0);
+ realWidth = MinOptMax.ZERO;
}
- wordSpaceCount += ai.wordSpaceCount;
- letterSpaceCount += ai.letterSpaceCount;
- realWidth.add(ai.areaIPD);
+ wordSpaceCount += areaInfo.wordSpaceCount;
+ letterSpaceCount += areaInfo.letterSpaceCount;
+ realWidth = realWidth.plus(areaInfo.areaIPD);
lastAreaInfoIndex = tbpNext.getLeafPos();
- lastAi = ai;
+ lastAreaInfo = areaInfo;
}
}
- if (lastAi != null) {
- this.addAreaInfoAreas(lastAi, wordSpaceCount, letterSpaceCount,
- firstAreaInfoIndex, lastAreaInfoIndex, realWidth, context);
+ if (lastAreaInfo != null) {
+ addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
+ lastAreaInfoIndex, realWidth, context);
}
}
- private void addAreaInfoAreas(final AreaInfo ai, final int wordSpaceCount,
- int letterSpaceCount, final int firstAreaInfoIndex,
- final int lastAreaInfoIndex, final MinOptMax realWidth, final LayoutContext context) {
+ private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
+ int firstAreaInfoIndex, int lastAreaInfoIndex,
+ MinOptMax realWidth, LayoutContext context) {
// TODO: These two statements (if, for) were like this before my recent
// changes. However, it seems as if they should use the AreaInfo from
- // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last ai.
+ // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last areaInfo.
// This needs to be checked.
- final int textLength = ai.breakIndex - ai.startIndex;
- if (ai.letterSpaceCount == textLength && !ai.isHyphenated
- && context.isLastArea()) {
+ int textLength = areaInfo.getCharLength();
+ if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated
+ && context.isLastArea()) {
// the line ends at a character like "/" or "-";
// remove the letter space after the last character
- realWidth.add(MinOptMax.multiply(this.letterSpaceIPD, -1));
+ realWidth = realWidth.minus(letterSpaceIPD);
letterSpaceCount--;
}
- for (int i = ai.startIndex; i < ai.breakIndex; i++) {
- final MinOptMax ladj = this.letterAdjustArray[i + 1];
- if (ladj != null && ladj.isElastic()) {
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ MinOptMax letterAdjustment = letterAdjustArray[i + 1];
+ if (letterAdjustment != null && letterAdjustment.isElastic()) {
letterSpaceCount++;
}
}
// add hyphenation character if the last word is hyphenated
- if (context.isLastArea() && ai.isHyphenated) {
- realWidth.add(new MinOptMax(this.hyphIPD));
+ if (context.isLastArea() && areaInfo.isHyphenated) {
+ realWidth = realWidth.plus(hyphIPD);
}
- // Calculate adjustments
- int difference = 0;
- int totalAdjust = 0;
- int wordSpaceDim = this.wordSpaceIPD.opt;
- int letterSpaceDim = this.letterSpaceIPD.opt;
- final double ipdAdjust = context.getIPDAdjust();
+ /* Calculate adjustments */
+ double ipdAdjust = context.getIPDAdjust();
// calculate total difference between real and available width
+ int difference;
if (ipdAdjust > 0.0) {
- difference = (int) ((realWidth.max - realWidth.opt)
- * ipdAdjust);
+ difference = (int) (realWidth.getStretch() * ipdAdjust);
} else {
- difference = (int) ((realWidth.opt - realWidth.min)
- * ipdAdjust);
+ difference = (int) (realWidth.getShrink() * ipdAdjust);
}
// set letter space adjustment
+ int letterSpaceDim = letterSpaceIPD.getOpt();
if (ipdAdjust > 0.0) {
- letterSpaceDim
- += (int) ((this.letterSpaceIPD.max - this.letterSpaceIPD.opt)
- * ipdAdjust);
- } else {
- letterSpaceDim
- += (int) ((this.letterSpaceIPD.opt - this.letterSpaceIPD.min)
- * ipdAdjust);
+ letterSpaceDim += (int) (letterSpaceIPD.getStretch() * ipdAdjust);
+ } else {
+ letterSpaceDim += (int) (letterSpaceIPD.getShrink() * ipdAdjust);
}
- totalAdjust += (letterSpaceDim - this.letterSpaceIPD.opt) * letterSpaceCount;
+ int totalAdjust = (letterSpaceDim - letterSpaceIPD.getOpt()) * letterSpaceCount;
// set word space adjustment
- //
+ int wordSpaceDim = wordSpaceIPD.getOpt();
if (wordSpaceCount > 0) {
wordSpaceDim += (difference - totalAdjust) / wordSpaceCount;
}
- totalAdjust += (wordSpaceDim - this.wordSpaceIPD.opt) * wordSpaceCount;
+ totalAdjust += (wordSpaceDim - wordSpaceIPD.getOpt()) * wordSpaceCount;
if (totalAdjust != difference) {
// the applied adjustment is greater or smaller than the needed one
TextLayoutManager.LOG
@@ -370,9 +365,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
totalAdjust = difference;
}
- final TextArea t = this.createTextArea(realWidth, totalAdjust, context,
- this.wordSpaceIPD.opt - this.spaceCharIPD, firstAreaInfoIndex,
- lastAreaInfoIndex, context.isLastArea(), ai.font);
+ TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
+ lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
@@ -386,133 +380,205 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// = spaceCharIPD + letterSpaceAdjust +
// + (wordSpaceDim - spaceCharIPD - 2 * letterSpaceAdjust)
// = wordSpaceDim - letterSpaceAdjust
- t.setTextLetterSpaceAdjust(letterSpaceDim);
- t.setTextWordSpaceAdjust(wordSpaceDim - this.spaceCharIPD
- - 2 * t.getTextLetterSpaceAdjust());
+ textArea.setTextLetterSpaceAdjust(letterSpaceDim);
+ textArea.setTextWordSpaceAdjust(wordSpaceDim - spaceCharIPD
+ - 2 * textArea.getTextLetterSpaceAdjust());
if (context.getIPDAdjust() != 0) {
// add information about space width
- t.setSpaceDifference(this.wordSpaceIPD.opt - this.spaceCharIPD
- - 2 * t.getTextLetterSpaceAdjust());
+ textArea.setSpaceDifference(wordSpaceIPD.getOpt() - spaceCharIPD
+ - 2 * textArea.getTextLetterSpaceAdjust());
}
- this.parentLM.addChildArea(t);
+ parentLayoutManager.addChildArea(textArea);
}
- /**
- * Create an inline word area.
- * This creates a TextArea and sets up the various attributes.
- *
- * @param width the MinOptMax width of the content
- * @param adjust the total ipd adjustment with respect to the optimal width
- * @param context the layout context
- * @param spaceDiff unused
- * @param firstIndex the index of the first AreaInfo used for the TextArea
- * @param lastIndex the index of the last AreaInfo used for the TextArea
- * @param isLastArea is this TextArea the last in a line?
- * @param font Font to be used in this particular TextArea
- * @return the new text area
- */
- protected TextArea createTextArea(final MinOptMax width, final int adjust,
- final LayoutContext context, final int spaceDiff, final int firstIndex,
- final int lastIndex, final boolean isLastArea, final Font font) {
- TextArea textArea;
- if (context.getIPDAdjust() == 0.0) {
- // create just a TextArea
- textArea = new TextArea();
- } else {
- // justified area: create a TextArea with extra info
- // about potential adjustments
- textArea = new TextArea(width.max - width.opt,
- width.opt - width.min,
- adjust);
+ private final class TextAreaBuilder {
+
+ private final MinOptMax width;
+ private final int adjust;
+ private final LayoutContext context;
+ private final int firstIndex;
+ private final int lastIndex;
+ private final boolean isLastArea;
+ private final Font font;
+
+ private int blockProgressionDimension;
+ private AreaInfo areaInfo;
+ private StringBuffer wordChars;
+ private int[] letterAdjust;
+ private int letterAdjustIndex;
+
+ private TextArea textArea;
+
+ /**
+ * Creates a new <code>TextAreaBuilder</code> which itself builds an inline word area. This
+ * creates a TextArea and sets up the various attributes.
+ *
+ * @param width the MinOptMax width of the content
+ * @param adjust the total ipd adjustment with respect to the optimal width
+ * @param context the layout context
+ * @param firstIndex the index of the first AreaInfo used for the TextArea
+ * @param lastIndex the index of the last AreaInfo used for the TextArea
+ * @param isLastArea is this TextArea the last in a line?
+ * @param font Font to be used in this particular TextArea
+ */
+ private TextAreaBuilder(MinOptMax width, int adjust, LayoutContext context,
+ int firstIndex, int lastIndex, boolean isLastArea, Font font) {
+ this.width = width;
+ this.adjust = adjust;
+ this.context = context;
+ this.firstIndex = firstIndex;
+ this.lastIndex = lastIndex;
+ this.isLastArea = isLastArea;
+ this.font = font;
}
- textArea.setIPD(width.opt + adjust);
- textArea.setBPD(font.getAscender() - font.getDescender());
- textArea.setBaselineOffset(font.getAscender());
- if (textArea.getBPD() == this.alignmentContext.getHeight()) {
- textArea.setOffset(0);
- } else {
- textArea.setOffset(this.alignmentContext.getOffset());
+ private TextArea build() {
+ createTextArea();
+ setInlineProgressionDimension();
+ calcBlockProgressionDimension();
+ setBlockProgressionDimension();
+ setBaselineOffset();
+ setOffset();
+ setText();
+ TraitSetter.addFontTraits(textArea, font);
+ textArea.addTrait(Trait.COLOR, foText.getColor());
+ TraitSetter.addPtr(textArea, getPtr()); // used for accessibility
+ TraitSetter.addTextDecoration(textArea, foText.getTextDecoration());
+ TraitSetter.addFontTraits(textArea, font);
+ return textArea;
}
- // set the text of the TextArea, split into words and spaces
- int wordStartIndex = -1;
- AreaInfo areaInfo;
- int len = 0;
- for (int i = firstIndex; i <= lastIndex; i++) {
- areaInfo = (AreaInfo) this.vecAreaInfo.get(i);
- if (areaInfo.isSpace) {
- // areaInfo stores information about spaces
- // add the spaces - except zero-width spaces - to the TextArea
- for (int j = areaInfo.startIndex; j < areaInfo.breakIndex; j++) {
- final char spaceChar = this.foText.charAt(j);
- if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
- textArea.addSpace(spaceChar, 0,
- CharUtilities.isAdjustableSpace(spaceChar));
- }
- }
+ /**
+ * Creates an plain <code>TextArea</code> or a justified <code>TextArea</code> with
+ * additional information.
+ */
+ private void createTextArea() {
+ if (context.getIPDAdjust() == 0.0) {
+ textArea = new TextArea();
} else {
- // areaInfo stores information about a word fragment
- if (wordStartIndex == -1) {
- // here starts a new word
- wordStartIndex = i;
- len = 0;
- }
- len += areaInfo.breakIndex - areaInfo.startIndex;
- if (i == lastIndex || ((AreaInfo) this.vecAreaInfo.get(i + 1)).isSpace) {
- // here ends a new word
- // add a word to the TextArea
- if (isLastArea
- && i == lastIndex
- && areaInfo.isHyphenated) {
- len++;
- }
- final StringBuffer wordChars = new StringBuffer(len);
- final int[] letterAdjust = new int[len];
- int letter = 0;
- for (int j = wordStartIndex; j <= i; j++) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(j);
- int lsCount = ai.letterSpaceCount;
- /* TODO: in Java 5, StringBuffer has an append() variant
- * for CharSequence, so the below iteration can be replaced
- * by:
- * wordChars.append(this.foText, ai.startIndex,
- * ai.breakIndex - ai.startIndex);
- */
- for (int ci = ai.startIndex; ci < ai.breakIndex; ci++) {
- wordChars.append(this.foText.charAt(ci));
- }
- for (int k = 0; k < ai.breakIndex - ai.startIndex; k++) {
- final MinOptMax adj = this.letterAdjustArray[ai.startIndex + k];
- if (letter > 0) {
- letterAdjust[letter] = adj == null ? 0
- : adj.opt;
- }
- if (lsCount > 0) {
- letterAdjust[letter] += textArea.getTextLetterSpaceAdjust();
- lsCount--;
- }
- letter++;
- }
+ textArea = new TextArea(width.getStretch(), width.getShrink(),
+ adjust);
+ }
+ }
+
+ private void setInlineProgressionDimension() {
+ textArea.setIPD(width.getOpt() + adjust);
+ }
+
+ private void calcBlockProgressionDimension() {
+ blockProgressionDimension = font.getAscender() - font.getDescender();
+ }
+
+ private void setBlockProgressionDimension() {
+ textArea.setBPD(blockProgressionDimension);
+ }
+
+ private void setBaselineOffset() {
+ textArea.setBaselineOffset(font.getAscender());
+ }
+
+ private void setOffset() {
+ if (blockProgressionDimension == alignmentContext.getHeight()) {
+ textArea.setOffset(0);
+ } else {
+ textArea.setOffset(alignmentContext.getOffset());
+ }
+ }
+
+ /**
+ * Sets the text of the TextArea, split into words and spaces.
+ */
+ private void setText() {
+ int wordStartIndex = -1;
+ int wordCharLength = 0;
+ for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) {
+ areaInfo = getAreaInfo(wordIndex);
+ if (areaInfo.isSpace) {
+ addSpaces();
+ } else {
+ // areaInfo stores information about a word fragment
+ if (wordStartIndex == -1) {
+ // here starts a new word
+ wordStartIndex = wordIndex;
+ wordCharLength = 0;
}
- // String wordChars = new String(textArray, wordStartIndex, len);
- if (isLastArea
- && i == lastIndex
- && areaInfo.isHyphenated) {
- // add the hyphenation character
- wordChars.append(this.foText.getCommonHyphenation().getHyphChar(font));
+ wordCharLength += areaInfo.getCharLength();
+ if (isWordEnd(wordIndex)) {
+ addWord(wordStartIndex, wordIndex, wordCharLength);
+ wordStartIndex = -1;
}
- textArea.addWord(wordChars.toString(), 0, letterAdjust);
- wordStartIndex = -1;
}
}
}
- TraitSetter.addFontTraits(textArea, font);
- textArea.addTrait(Trait.COLOR, this.foText.getColor());
- TraitSetter.addPtr(textArea, getPtr()); // used for accessibility
- TraitSetter.addTextDecoration(textArea, this.foText.getTextDecoration());
- return textArea;
+ private boolean isWordEnd(int areaInfoIndex) {
+ return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace;
+ }
+
+ private void addWord(int startIndex, int endIndex, int charLength) {
+ if (isHyphenated(endIndex)) {
+ charLength++;
+ }
+ initWord(charLength);
+ for (int i = startIndex; i <= endIndex; i++) {
+ AreaInfo wordAreaInfo = getAreaInfo(i);
+ addWordChars(wordAreaInfo);
+ addLetterAdjust(wordAreaInfo);
+ }
+ if (isHyphenated(endIndex)) {
+ addHyphenationChar();
+ }
+ textArea.addWord(wordChars.toString(), 0, letterAdjust);
+ }
+
+ private void initWord(int charLength) {
+ wordChars = new StringBuffer(charLength);
+ letterAdjust = new int[charLength];
+ letterAdjustIndex = 0;
+ }
+
+ private boolean isHyphenated(int endIndex) {
+ return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated;
+ }
+
+ private void addHyphenationChar() {
+ wordChars.append(foText.getCommonHyphenation().getHyphChar(font));
+ }
+
+ private void addWordChars(AreaInfo wordAreaInfo) {
+ for (int i = wordAreaInfo.startIndex; i < wordAreaInfo.breakIndex; i++) {
+ wordChars.append(foText.charAt(i));
+ }
+ }
+
+ private void addLetterAdjust(AreaInfo wordAreaInfo) {
+ int letterSpaceCount = wordAreaInfo.letterSpaceCount;
+ for (int i = wordAreaInfo.startIndex; i < wordAreaInfo.breakIndex; i++) {
+ if (letterAdjustIndex > 0) {
+ MinOptMax adj = letterAdjustArray[i];
+ letterAdjust[letterAdjustIndex] = adj == null ? 0 : adj.getOpt();
+ }
+ if (letterSpaceCount > 0) {
+ letterAdjust[letterAdjustIndex] += textArea.getTextLetterSpaceAdjust();
+ letterSpaceCount--;
+ }
+ letterAdjustIndex++;
+ }
+ }
+
+ /**
+ * The <code>AreaInfo</code> stores information about spaces.
+ * <p/>
+ * Add the spaces - except zero-width spaces - to the TextArea.
+ */
+ private void addSpaces() {
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ char spaceChar = foText.charAt(i);
+ if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
+ textArea.addSpace(spaceChar, 0, CharUtilities.isAdjustableSpace(spaceChar));
+ }
+ }
+ }
}
/**
@@ -520,7 +586,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* @return ptr of fobj
*/
private String getPtr() {
- FObj fobj = this.parentLM.getFObj();
+ FObj fobj = parentLayoutManager.getFObj();
if (fobj instanceof StructurePointerPropertySet) {
return (((StructurePointerPropertySet) fobj).getPtr());
} else {
@@ -529,11 +595,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
}
- private void addToLetterAdjust(final int index, final int width) {
- if (this.letterAdjustArray[index] == null) {
- this.letterAdjustArray[index] = new MinOptMax(width);
+ private AreaInfo getAreaInfo(int index) {
+ return (AreaInfo) areaInfos.get(index);
+ }
+
+ private void addToLetterAdjust(int index, int width) {
+ if (letterAdjustArray[index] == null) {
+ letterAdjustArray[index] = MinOptMax.getInstance(width);
} else {
- this.letterAdjustArray[index].add(width);
+ letterAdjustArray[index] = letterAdjustArray[index].plus(width);
}
}
@@ -544,32 +614,33 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
*/
private static boolean isSpace(final char ch) {
return ch == CharUtilities.SPACE
- || CharUtilities.isNonBreakableSpace(ch)
- || CharUtilities.isFixedWidthSpace(ch);
+ || CharUtilities.isNonBreakableSpace(ch)
+ || CharUtilities.isFixedWidthSpace(ch);
}
/** {@inheritDoc} */
public List getNextKnuthElements(final LayoutContext context, final int alignment) {
- this.lineStartBAP = context.getLineStartBorderAndPaddingWidth();
- this.lineEndBAP = context.getLineEndBorderAndPaddingWidth();
- this.alignmentContext = context.getAlignmentContext();
+ lineStartBAP = context.getLineStartBorderAndPaddingWidth();
+ lineEndBAP = context.getLineEndBorderAndPaddingWidth();
+ alignmentContext = context.getAlignmentContext();
final List returnList = new LinkedList();
KnuthSequence sequence = new InlineKnuthSequence();
- AreaInfo ai = null;
- AreaInfo prevAi = null;
+ AreaInfo areaInfo = null;
+ AreaInfo prevAreaInfo = null;
returnList.add(sequence);
- final LineBreakStatus lbs = new LineBreakStatus();
- this.thisStart = this.nextStart;
+ LineBreakStatus lineBreakStatus = new LineBreakStatus();
+ thisStart = nextStart;
boolean inWord = false;
boolean inWhitespace = false;
char ch = 0;
- while (this.nextStart < this.foText.length()) {
- ch = this.foText.charAt(this.nextStart);
+ while (nextStart < foText.length()) {
+ ch = foText.charAt(nextStart);
boolean breakOpportunity = false;
- final byte breakAction = this.keepTogether ? LineBreakStatus.PROHIBITED_BREAK
- : lbs.nextChar(ch);
+ byte breakAction = keepTogether
+ ? LineBreakStatus.PROHIBITED_BREAK
+ : lineBreakStatus.nextChar(ch);
switch (breakAction) {
case LineBreakStatus.COMBINING_PROHIBITED_BREAK:
case LineBreakStatus.PROHIBITED_BREAK:
@@ -589,62 +660,58 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
|| TextLayoutManager.isSpace(ch)
|| CharUtilities.isExplicitBreak(ch)) {
// this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
- prevAi = this.processWord(alignment, sequence, prevAi, ch,
+ prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch,
breakOpportunity, true);
}
} else if (inWhitespace) {
if (ch != CharUtilities.SPACE || breakOpportunity) {
- prevAi = this.processWhitespace(alignment, sequence,
- breakOpportunity);
+ prevAreaInfo = processWhitespace(alignment, sequence, breakOpportunity);
}
} else {
- if (ai != null) {
- prevAi = ai;
- ai = this.processLeftoverAi(alignment, sequence, ai, ch,
+ if (areaInfo != null) {
+ prevAreaInfo = areaInfo;
+ processLeftoverAreaInfo(alignment, sequence, areaInfo,
ch == CharUtilities.SPACE || breakOpportunity);
+ areaInfo = null;
}
if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
- sequence = this.processLinebreak(returnList, sequence);
+ sequence = processLinebreak(returnList, sequence);
}
}
if (ch == CharUtilities.SPACE
- && this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE
+ && foText.getWhitespaceTreatment() == Constants.EN_PRESERVE
|| ch == CharUtilities.NBSPACE) {
// preserved space or non-breaking space:
// create the AreaInfo object
- ai = new AreaInfo(this.nextStart, this.nextStart + 1,
- 1, 0, this.wordSpaceIPD, false, true,
- breakOpportunity, this.spaceFont);
- this.thisStart = this.nextStart + 1;
+ areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
+ breakOpportunity, spaceFont);
+ thisStart = nextStart + 1;
} else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
// create the AreaInfo object
- final Font font = FontSelector.selectFontForCharacterInText(ch,
- this.foText, this);
- final MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
- ai = new AreaInfo(this.nextStart, this.nextStart + 1,
- 0, 0, ipd, false, true,
+ Font font = FontSelector.selectFontForCharacterInText(ch, foText, this);
+ MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(ch));
+ areaInfo = new AreaInfo(nextStart, nextStart + 1, 0, 0, ipd, false, true,
breakOpportunity, font);
- this.thisStart = this.nextStart + 1;
+ thisStart = nextStart + 1;
} else if (CharUtilities.isExplicitBreak(ch)) {
//mandatory break-character: only advance index
- this.thisStart = this.nextStart + 1;
+ thisStart = nextStart + 1;
}
- inWord = !TextLayoutManager.isSpace(ch)
- && !CharUtilities.isExplicitBreak(ch);
+ inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
- && this.foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
- this.nextStart++;
- } // end of while
+ && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
+ nextStart++;
+ }
// Process any last elements
if (inWord) {
- this.processWord(alignment, sequence, prevAi, ch, false, false);
+ processWord(alignment, sequence, prevAreaInfo, ch, false, false);
} else if (inWhitespace) {
- this.processWhitespace(alignment, sequence, true);
- } else if (ai != null) {
- this.processLeftoverAi(alignment, sequence, ai, ch,
+ processWhitespace(alignment, sequence, true);
+ } else if (areaInfo != null) {
+ processLeftoverAreaInfo(alignment, sequence, areaInfo,
ch == CharUtilities.ZERO_WIDTH_SPACE);
} else if (CharUtilities.isExplicitBreak(ch)) {
this.processLinebreak(returnList, sequence);
@@ -655,7 +722,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
ListUtil.removeLast(returnList);
}
- this.setFinished(true);
+ setFinished(true);
if (returnList.isEmpty()) {
return null;
} else {
@@ -663,12 +730,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
}
- private KnuthSequence processLinebreak(final List returnList,
- KnuthSequence sequence) {
- if (this.lineEndBAP != 0) {
- sequence.add(
- new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, true));
+ private KnuthSequence processLinebreak(List returnList, KnuthSequence sequence) {
+ if (lineEndBAP != 0) {
+ sequence.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, true));
}
sequence.endSequence();
sequence = new InlineKnuthSequence();
@@ -676,32 +740,29 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
return sequence;
}
- private AreaInfo processLeftoverAi(final int alignment,
- final KnuthSequence sequence, AreaInfo ai, final char ch,
- final boolean breakOpportunityAfter) {
- this.vecAreaInfo.add(ai);
- ai.breakOppAfter = breakOpportunityAfter;
- this.addElementsForASpace(sequence, alignment, ai, this.vecAreaInfo.size() - 1);
- ai = null;
- return ai;
+ private void processLeftoverAreaInfo(int alignment,
+ KnuthSequence sequence, AreaInfo areaInfo,
+ boolean breakOpportunityAfter) {
+ areaInfos.add(areaInfo);
+ areaInfo.breakOppAfter = breakOpportunityAfter;
+ addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
}
private AreaInfo processWhitespace(final int alignment,
final KnuthSequence sequence, final boolean breakOpportunity) {
// End of whitespace
// create the AreaInfo object
- AreaInfo ai = new AreaInfo(this.thisStart, this.nextStart,
- this.nextStart - this.thisStart, 0,
- MinOptMax.multiply(this.wordSpaceIPD, this.nextStart
- - this.thisStart), false, true,
- breakOpportunity, this.spaceFont);
- this.vecAreaInfo.add(ai);
+ assert nextStart >= thisStart;
+ AreaInfo areaInfo = new AreaInfo(thisStart, nextStart, nextStart - thisStart, 0,
+ wordSpaceIPD.mult(nextStart - thisStart), false, true, breakOpportunity, spaceFont);
+
+ areaInfos.add(areaInfo);
// create the elements
- this.addElementsForASpace(sequence, alignment, ai, this.vecAreaInfo.size() - 1);
+ addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
- this.thisStart = this.nextStart;
- return ai;
+ thisStart = nextStart;
+ return areaInfo;
}
private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
@@ -709,39 +770,36 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
final boolean checkEndsWithHyphen) {
//Word boundary found, process widths and kerning
- int lastIndex = this.nextStart;
- while (lastIndex > 0
- && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
+ int lastIndex = nextStart;
+ while (lastIndex > 0 && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
lastIndex--;
}
final boolean endsWithHyphen = checkEndsWithHyphen
&& foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
- final Font font = FontSelector
- .selectFontForCharactersInText(foText,
- this.thisStart, lastIndex, foText, this);
- final int wordLength = lastIndex - this.thisStart;
- final boolean kerning = font.hasKerning();
- final MinOptMax wordIPD = new MinOptMax(0);
- for (int i = this.thisStart; i < lastIndex; i++) {
- final char currentChar = foText.charAt(i);
+ Font font = FontSelector.selectFontForCharactersInText(foText, thisStart, lastIndex, foText, this);
+ int wordLength = lastIndex - thisStart;
+ boolean kerning = font.hasKerning();
+ MinOptMax wordIPD = MinOptMax.ZERO;
+ for (int i = thisStart; i < lastIndex; i++) {
+ char currentChar = foText.charAt(i);
//character width
- final int charWidth = font.getCharWidth(currentChar);
- wordIPD.add(charWidth);
+ int charWidth = font.getCharWidth(currentChar);
+ wordIPD = wordIPD.plus(charWidth);
//kerning
if (kerning) {
int kern = 0;
- if (i > this.thisStart) {
- final char previousChar = foText.charAt(i - 1);
+ if (i > thisStart) {
+ char previousChar = foText.charAt(i - 1);
kern = font.getKernValue(previousChar, currentChar);
} else if (prevAreaInfo != null && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
- final char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
+ char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
kern = font.getKernValue(previousChar, currentChar);
}
if (kern != 0) {
- this.addToLetterAdjust(i, kern);
- wordIPD.add(kern);
+ addToLetterAdjust(i, kern);
+ wordIPD = wordIPD.plus(kern);
}
}
}
@@ -752,7 +810,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
&& endsWithHyphen) {
final int kern = font.getKernValue(foText.charAt(lastIndex - 1), ch);
if (kern != 0) {
- this.addToLetterAdjust(lastIndex, kern);
+ addToLetterAdjust(lastIndex, kern);
//TODO: add kern to wordIPD?
}
}
@@ -763,21 +821,21 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
if (breakOpportunity && !TextLayoutManager.isSpace(ch)) {
iLetterSpaces++;
}
- wordIPD.add(MinOptMax.multiply(this.letterSpaceIPD, iLetterSpaces));
+ assert iLetterSpaces >= 0;
+ wordIPD = wordIPD.plus(letterSpaceIPD.mult(iLetterSpaces));
// create the AreaInfo object
- AreaInfo areaInfo = new AreaInfo(this.thisStart, lastIndex, 0,
+ AreaInfo areaInfo = new AreaInfo(thisStart, lastIndex, 0,
iLetterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunity, font);
prevAreaInfo = areaInfo;
- this.vecAreaInfo.add(areaInfo);
- this.tempStart = this.nextStart;
+ areaInfos.add(areaInfo);
+ tempStart = nextStart;
//add the elements
- this.addElementsForAWordFragment(sequence, alignment, areaInfo,
- this.vecAreaInfo.size() - 1, this.letterSpaceIPD);
- this.thisStart = this.nextStart;
+ addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ thisStart = nextStart;
return prevAreaInfo;
}
@@ -788,49 +846,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// look at the Position stored in the first element in oldList
// which is always a box
ListIterator oldListIterator = oldList.listIterator();
- final KnuthElement el = (KnuthElement)oldListIterator.next();
- final LeafPosition pos = (LeafPosition) ((KnuthBox) el).getPosition();
- final int idx = pos.getLeafPos();
+ KnuthElement knuthElement = (KnuthElement) oldListIterator.next();
+ LeafPosition pos = (LeafPosition) ((KnuthBox) knuthElement).getPosition();
+ int index = pos.getLeafPos();
//element could refer to '-1' position, for non-collapsed spaces (?)
- if (idx > -1) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(idx);
- ai.letterSpaceCount++;
- ai.areaIPD.add(this.letterSpaceIPD);
- if (TextLayoutManager.BREAK_CHARS.indexOf(this.foText.charAt(this.tempStart - 1)) >= 0) {
+ if (index > -1) {
+ AreaInfo areaInfo = getAreaInfo(index);
+ areaInfo.letterSpaceCount++;
+ areaInfo.addToAreaIPD(letterSpaceIPD);
+ if (TextLayoutManager.BREAK_CHARS.indexOf(foText.charAt(tempStart - 1)) >= 0) {
// the last character could be used as a line break
// append new elements to oldList
oldListIterator = oldList.listIterator(oldList.size());
oldListIterator.add(new KnuthPenalty(0, KnuthPenalty.FLAGGED_PENALTY, true,
- this.auxiliaryPosition, false));
- oldListIterator.add(new KnuthGlue(this.letterSpaceIPD.opt,
- this.letterSpaceIPD.max - this.letterSpaceIPD.opt,
- this.letterSpaceIPD.opt - this.letterSpaceIPD.min,
- this.auxiliaryPosition, false));
- } else if (this.letterSpaceIPD.min == this.letterSpaceIPD.max) {
+ auxiliaryPosition, false));
+ oldListIterator.add(new KnuthGlue(letterSpaceIPD, auxiliaryPosition, false));
+ } else if (letterSpaceIPD.isStiff()) {
// constant letter space: replace the box
- oldListIterator.set(new KnuthInlineBox(ai.areaIPD.opt,
- this.alignmentContext, pos, false));
+ oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(),
+ alignmentContext, pos, false));
} else {
// adjustable letter space: replace the glue
oldListIterator.next(); // this would return the penalty element
oldListIterator.next(); // this would return the glue element
- oldListIterator
- .set(new KnuthGlue(
- ai.letterSpaceCount * this.letterSpaceIPD.opt,
- ai.letterSpaceCount
- * (this.letterSpaceIPD.max - this.letterSpaceIPD.opt),
- ai.letterSpaceCount
- * (this.letterSpaceIPD.opt - this.letterSpaceIPD.min),
- this.auxiliaryPosition, true));
+ oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaceCount),
+ auxiliaryPosition, true));
}
}
return oldList;
}
/**
- * remove the AreaInfo object represented by the given elements,
- * so that it won't generate any element when getChangedKnuthElements
- * will be called
+ * Removes the <code>AreaInfo</code> object represented by the given elements, so that it won't
+ * generate any element when <code>getChangedKnuthElements</code> is called.
*
* @param oldList the elements representing the word space
*/
@@ -848,99 +896,91 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
oldListIterator.next();
oldListIterator.next();
}
- final int leafValue = ((LeafPosition) ((KnuthElement) oldListIterator
- .next()).getPosition()).getLeafPos();
+ KnuthElement knuthElement = (KnuthElement) oldListIterator.next();
+ int leafValue = ((LeafPosition) knuthElement.getPosition()).getLeafPos();
// only the last word space can be a trailing space!
- if (leafValue == this.vecAreaInfo.size() - 1) {
- this.vecAreaInfo.remove(leafValue);
+ if (leafValue == areaInfos.size() - 1) {
+ areaInfos.remove(leafValue);
} else {
TextLayoutManager.LOG.error("trying to remove a non-trailing word space");
}
}
- /** {@inheritDoc} */
- public void hyphenate(final Position pos, final HyphContext hc) {
- final AreaInfo ai
- = (AreaInfo) this.vecAreaInfo.get(((LeafPosition) pos).getLeafPos());
- int startIndex = ai.startIndex;
+ /**
+ * {@inheritDoc}
+ */
+ public void hyphenate(Position pos, HyphContext hyphContext) {
+ AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos());
+ int startIndex = areaInfo.startIndex;
int stopIndex;
boolean nothingChanged = true;
- final Font font = ai.font;
+ Font font = areaInfo.font;
- while (startIndex < ai.breakIndex) {
- final MinOptMax newIPD = new MinOptMax(0);
+ while (startIndex < areaInfo.breakIndex) {
+ MinOptMax newIPD = MinOptMax.ZERO;
boolean hyphenFollows;
- stopIndex = startIndex + hc.getNextHyphPoint();
- if (hc.hasMoreHyphPoints() && stopIndex <= ai.breakIndex) {
+ stopIndex = startIndex + hyphContext.getNextHyphPoint();
+ if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) {
// stopIndex is the index of the first character
// after a hyphenation point
hyphenFollows = true;
} else {
// there are no more hyphenation points,
- // or the next one is after ai.breakIndex
+ // or the next one is after areaInfo.breakIndex
hyphenFollows = false;
- stopIndex = ai.breakIndex;
+ stopIndex = areaInfo.breakIndex;
}
- hc.updateOffset(stopIndex - startIndex);
+ hyphContext.updateOffset(stopIndex - startIndex);
//log.info("Word: " + new String(textArray, startIndex, stopIndex - startIndex));
for (int i = startIndex; i < stopIndex; i++) {
- final char c = this.foText.charAt(i);
- newIPD.add(new MinOptMax(font.getCharWidth(c)));
+ char ch = foText.charAt(i);
+ newIPD = newIPD.plus(font.getCharWidth(ch));
//if (i > startIndex) {
if (i < stopIndex) {
- MinOptMax la = this.letterAdjustArray[i + 1];
+ MinOptMax letterAdjust = letterAdjustArray[i + 1];
if (i == stopIndex - 1 && hyphenFollows) {
//the letter adjust here needs to be handled further down during
//element generation because it depends on hyph/no-hyph condition
- la = null;
+ letterAdjust = null;
}
- if (la != null) {
- newIPD.add(la);
+ if (letterAdjust != null) {
+ newIPD = newIPD.plus(letterAdjust);
}
}
}
+
// add letter spaces
- final boolean isWordEnd
- = stopIndex == ai.breakIndex
- && ai.letterSpaceCount < ai.breakIndex - ai.startIndex;
- newIPD.add(MinOptMax.multiply(this.letterSpaceIPD,
- (isWordEnd
- ? stopIndex - startIndex - 1
- : stopIndex - startIndex)));
-
- if (!(nothingChanged
- && stopIndex == ai.breakIndex
- && !hyphenFollows)) {
+ boolean isWordEnd = stopIndex == areaInfo.breakIndex && areaInfo.letterSpaceCount < areaInfo.getCharLength();
+ int letterSpaceCount = isWordEnd ? stopIndex - startIndex - 1 : stopIndex - startIndex;
+
+ assert letterSpaceCount >= 0;
+ newIPD = newIPD.plus(letterSpaceIPD.mult(letterSpaceCount));
+
+ if (!(nothingChanged && stopIndex == areaInfo.breakIndex && !hyphenFollows)) {
// the new AreaInfo object is not equal to the old one
- if (this.changeList == null) {
- this.changeList = new LinkedList();
- }
- this.changeList.add(new PendingChange(new AreaInfo(
- startIndex, stopIndex, 0,
- (isWordEnd ? stopIndex - startIndex - 1
- : stopIndex - startIndex), newIPD,
- hyphenFollows, false, false, font),
+ changeList.add(new PendingChange(new AreaInfo(startIndex, stopIndex, 0,
+ letterSpaceCount, newIPD, hyphenFollows, false, false, font),
((LeafPosition) pos).getLeafPos()));
nothingChanged = false;
}
startIndex = stopIndex;
}
- this.hasChanged = (this.hasChanged || !nothingChanged);
+ hasChanged |= !nothingChanged;
}
/** {@inheritDoc} */
public boolean applyChanges(final List oldList) {
- this.setFinished(false);
+ setFinished(false);
- if (this.changeList != null && !this.changeList.isEmpty()) {
+ if (!changeList.isEmpty()) {
int areaInfosAdded = 0;
int areaInfosRemoved = 0;
int oldIndex = -1, changeIndex;
PendingChange currChange;
- final ListIterator changeListIterator = this.changeList.listIterator();
+ ListIterator changeListIterator = changeList.listIterator();
while (changeListIterator.hasNext()) {
currChange = (PendingChange) changeListIterator.next();
if (currChange.index == oldIndex) {
@@ -951,111 +991,109 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
areaInfosAdded++;
oldIndex = currChange.index;
changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
- this.vecAreaInfo.remove(changeIndex);
+ areaInfos.remove(changeIndex);
}
- this.vecAreaInfo.add(changeIndex, currChange.ai);
+ areaInfos.add(changeIndex, currChange.areaInfo);
}
- this.changeList.clear();
+ changeList.clear();
}
- this.returnedIndex = 0;
- return this.hasChanged;
+ returnedIndex = 0;
+ return hasChanged;
}
/** {@inheritDoc} */
- public List getChangedKnuthElements(final List oldList,
- final int alignment) {
- if (this.isFinished()) {
+ public List getChangedKnuthElements(final List oldList, final int alignment) {
+ if (isFinished()) {
return null;
}
final LinkedList returnList = new LinkedList();
- while (this.returnedIndex < this.vecAreaInfo.size()) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(this.returnedIndex);
- if (ai.wordSpaceCount == 0) {
- // ai refers either to a word or a word fragment
- this.addElementsForAWordFragment(returnList, alignment, ai,
- this.returnedIndex, this.letterSpaceIPD);
+ while (returnedIndex < areaInfos.size()) {
+ AreaInfo areaInfo = getAreaInfo(returnedIndex);
+ if (areaInfo.wordSpaceCount == 0) {
+ // areaInfo refers either to a word or a word fragment
+ addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndex);
} else {
- // ai refers to a space
- this.addElementsForASpace(returnList, alignment, ai, this.returnedIndex);
+ // areaInfo refers to a space
+ addElementsForASpace(returnList, alignment, areaInfo, returnedIndex);
}
- this.returnedIndex++;
- } // end of while
- this.setFinished(true);
+ returnedIndex++;
+ }
+ setFinished(true);
//ElementListObserver.observe(returnList, "text-changed", null);
return returnList;
}
- /** {@inheritDoc} */
- public void getWordChars(final StringBuffer sbChars, final Position pos) {
- final int leafValue = ((LeafPosition) pos).getLeafPos();
+ /**
+ * {@inheritDoc}
+ */
+ public String getWordChars(Position pos) {
+ int leafValue = ((LeafPosition) pos).getLeafPos();
if (leafValue != -1) {
- final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(leafValue);
- for (int i = ai.startIndex; i < ai.breakIndex; ++i) {
- sbChars.append(this.foText.charAt(i));
+ AreaInfo areaInfo = getAreaInfo(leafValue);
+ StringBuffer buffer = new StringBuffer(areaInfo.getCharLength());
+ for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ buffer.append(foText.charAt(i));
}
+ return buffer.toString();
+ } else {
+ return "";
}
}
- private void addElementsForASpace(final List baseList,
- final int alignment,
- final AreaInfo ai,
- final int leafValue) {
- final LeafPosition mainPosition = new LeafPosition(this, leafValue);
+ private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo,
+ int leafValue) {
+ LeafPosition mainPosition = new LeafPosition(this, leafValue);
- if (!ai.breakOppAfter) {
+ if (!areaInfo.breakOppAfter) {
// a non-breaking space
if (alignment == Constants.EN_JUSTIFY) {
// the space can stretch and shrink, and must be preserved
// when starting a line
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max - ai.areaIPD.opt,
- ai.areaIPD.opt - ai.areaIPD.min, mainPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false));
} else {
// the space does not need to stretch or shrink, and must be
// preserved when starting a line
- baseList.add(new KnuthInlineBox(ai.areaIPD.opt, null,
- mainPosition, true));
+ baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), null, mainPosition,
+ true));
}
} else {
- if (this.foText.charAt(ai.startIndex) != CharUtilities.SPACE
- || this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
+ if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE
+ || foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
- this.addElementsForBreakingSpace(baseList, alignment, ai,
- this.auxiliaryPosition, 0, mainPosition,
- ai.areaIPD.opt, true);
+ baseList.addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0,
+ mainPosition, areaInfo.areaIPD.getOpt(), true));
} else {
// a (possible block) of breaking spaces
- this.addElementsForBreakingSpace(baseList, alignment, ai,
- mainPosition, ai.areaIPD.opt,
- this.auxiliaryPosition, 0, false);
+ baseList.addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition,
+ areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false));
}
}
}
- private void addElementsForBreakingSpace(final List baseList,
- final int alignment, final AreaInfo ai, final Position pos2,
- final int p2WidthOffset, final Position pos3,
- final int p3WidthOffset, final boolean skipZeroCheck) {
+ private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2,
+ int p2WidthOffset, Position pos3,
+ int p3WidthOffset, boolean skipZeroCheck) {
+ List elements = new ArrayList();
+
switch (alignment) {
case EN_CENTER:
// centered text:
// if the second element is chosen as a line break these elements
// add a constant amount of stretch at the end of a line and at the
// beginning of the next one, otherwise they don't add any stretch
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), -6
+ elements.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP), -6
* LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset,
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos3, false));
break;
@@ -1065,246 +1103,203 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// if the second element is chosen as a line break these elements
// add a constant amount of stretch at the end of a line, otherwise
// they don't add any stretch
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
+ if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
+ elements.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP), -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
} else {
- baseList.add(new KnuthGlue(0,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(ai.areaIPD.opt, -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- pos2, false));
+ elements.add(new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false));
}
break;
case EN_JUSTIFY:
// justified text:
// the stretch and shrink depends on the space width
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), ai.areaIPD.max
- - ai.areaIPD.opt, ai.areaIPD.opt - ai.areaIPD.min,
- pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
- } else {
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max
- - ai.areaIPD.opt, ai.areaIPD.opt - ai.areaIPD.min,
- pos2, false));
- }
+ elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink()));
break;
default:
// last line justified, the other lines unjustified:
// use only the space stretch
- if (skipZeroCheck || this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeZeroWidthPenalty(0));
- baseList.add(new KnuthGlue(p2WidthOffset
- - (this.lineStartBAP + this.lineEndBAP), ai.areaIPD.max
- - ai.areaIPD.opt, 0, pos2, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP + p3WidthOffset,
- 0, 0, pos3, false));
- } else {
- baseList.add(new KnuthGlue(ai.areaIPD.opt, ai.areaIPD.max
- - ai.areaIPD.opt, 0, pos2, false));
- }
+ elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, 0));
}
+ return elements;
}
- private void addElementsForAWordFragment(final List baseList,
- final int alignment,
- final AreaInfo ai,
- final int leafValue,
- final MinOptMax letterSpaceWidth) {
+ private List getElementsForJustifiedText(AreaInfo areaInfo, Position pos2, int p2WidthOffset,
+ Position pos3, int p3WidthOffset, boolean skipZeroCheck,
+ int shrinkability) {
+
+ int stretchability = areaInfo.areaIPD.getStretch();
+
+ List elements = new ArrayList();
+ if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
+ elements.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, false));
+ elements.add(makeZeroWidthPenalty(0));
+ elements.add(new KnuthGlue(p2WidthOffset - (lineStartBAP + lineEndBAP),
+ stretchability, shrinkability, pos2, false));
+ elements.add(makeAuxiliaryZeroWidthBox());
+ elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
+ } else {
+ elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), stretchability, shrinkability,
+ pos2, false));
+ }
+ return elements;
+ }
- final LeafPosition mainPosition = new LeafPosition(this, leafValue);
+ private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo,
+ int leafValue) {
+ LeafPosition mainPosition = new LeafPosition(this, leafValue);
// if the last character of the word fragment is '-' or '/',
// the fragment could end a line; in this case, it loses one
// of its letter spaces;
- final boolean suppressibleLetterSpace = ai.breakOppAfter && !ai.isHyphenated;
+ boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated;
- if (letterSpaceWidth.min == letterSpaceWidth.max) {
+ if (letterSpaceIPD.isStiff()) {
// constant letter spacing
- baseList.add(new KnuthInlineBox(
- suppressibleLetterSpace
- ? ai.areaIPD.opt - letterSpaceWidth.opt
- : ai.areaIPD.opt,
- this.alignmentContext,
- this.notifyPos(mainPosition), false));
+ baseList.add(new KnuthInlineBox(suppressibleLetterSpace
+ ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt()
+ : areaInfo.areaIPD.getOpt(),
+ alignmentContext, notifyPos(mainPosition), false));
} else {
// adjustable letter spacing
- final int unsuppressibleLetterSpaces
- = suppressibleLetterSpace ? ai.letterSpaceCount - 1 : ai.letterSpaceCount;
- baseList.add
- (new KnuthInlineBox(ai.areaIPD.opt
- - ai.letterSpaceCount * letterSpaceWidth.opt,
- this.alignmentContext,
- this.notifyPos(mainPosition), false));
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add
- (new KnuthGlue(unsuppressibleLetterSpaces * letterSpaceWidth.opt,
- unsuppressibleLetterSpaces * (letterSpaceWidth.max - letterSpaceWidth.opt),
- unsuppressibleLetterSpaces * (letterSpaceWidth.opt - letterSpaceWidth.min),
- this.auxiliaryPosition, true));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
+ int unsuppressibleLetterSpaces = suppressibleLetterSpace
+ ? areaInfo.letterSpaceCount - 1
+ : areaInfo.letterSpaceCount;
+ baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt()
+ - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(),
+ alignmentContext, notifyPos(mainPosition), false));
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces),
+ auxiliaryPosition, true));
+ baseList.add(makeAuxiliaryZeroWidthBox());
}
// extra-elements if the word fragment is the end of a syllable,
// or it ends with a character that can be used as a line break
- if (ai.isHyphenated) {
+ if (areaInfo.isHyphenated) {
MinOptMax widthIfNoBreakOccurs = null;
- if (ai.breakIndex < this.foText.length()) {
+ if (areaInfo.breakIndex < foText.length()) {
//Add in kerning in no-break condition
- widthIfNoBreakOccurs = this.letterAdjustArray[ai.breakIndex];
+ widthIfNoBreakOccurs = letterAdjustArray[areaInfo.breakIndex];
}
- //if (ai.breakIndex)
+ //if (areaInfo.breakIndex)
// the word fragment ends at the end of a syllable:
// if a break occurs the content width increases,
// otherwise nothing happens
- this.addElementsForAHyphen(baseList, alignment, this.hyphIPD,
- widthIfNoBreakOccurs, ai.breakOppAfter && ai.isHyphenated);
+ addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs,
+ areaInfo.breakOppAfter && areaInfo.isHyphenated);
} else if (suppressibleLetterSpace) {
// the word fragment ends with a character that acts as a hyphen
// if a break occurs the width does not increase,
// otherwise there is one more letter space
- this.addElementsForAHyphen(baseList, alignment, 0, letterSpaceWidth, true);
+ addElementsForAHyphen(baseList, alignment, 0, letterSpaceIPD, true);
}
}
- // static final int SOFT_HYPHEN_PENALTY = KnuthPenalty.FLAGGED_PENALTY / 10;
- private static final int SOFT_HYPHEN_PENALTY = 1;
+ private void addElementsForAHyphen(List baseList, int alignment, int widthIfBreakOccurs,
+ MinOptMax widthIfNoBreakOccurs, boolean unflagged) {
- private void addElementsForAHyphen(final List baseList,
- final int alignment,
- final int widthIfBreakOccurs,
- MinOptMax widthIfNoBreakOccurs,
- final boolean unflagged) {
if (widthIfNoBreakOccurs == null) {
- widthIfNoBreakOccurs = TextLayoutManager.ZERO_MINOPTMAX;
+ widthIfNoBreakOccurs = MinOptMax.ZERO;
}
switch (alignment) {
- case EN_CENTER :
+ case EN_CENTER:
// centered text:
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, true));
- baseList.add(new KnuthPenalty(this.hyphIPD,
- unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
- : KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(-(this.lineEndBAP + this.lineStartBAP),
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, true));
+ baseList.add(new KnuthPenalty(hyphIPD, unflagged
+ ? TextLayoutManager.SOFT_HYPHEN_PENALTY
+ : KnuthPenalty.FLAGGED_PENALTY, !unflagged, auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(-(lineEndBAP + lineStartBAP),
-6 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP,
- 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, true));
+ auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH,
+ 0, auxiliaryPosition, true));
break;
- case EN_START : // fall through
- case EN_END :
+ case EN_START: // fall through
+ case EN_END:
// left- or right-aligned text:
- if (this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP,
+ if (lineStartBAP != 0 || lineEndBAP != 0) {
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP,
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt
- - (this.lineStartBAP + this.lineEndBAP), -3
- * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP, 0, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt()
+ - (lineStartBAP + lineEndBAP),
+ -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 0, 0, auxiliaryPosition, false));
} else {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
baseList.add(new KnuthGlue(0, 3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt,
- -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt(),
+ -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
+ auxiliaryPosition, false));
}
break;
default:
// justified text, or last line justified:
// just a flagged penalty
- if (this.lineStartBAP != 0 || this.lineEndBAP != 0) {
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineEndBAP, 0, 0,
- this.auxiliaryPosition, false));
+ if (lineStartBAP != 0 || lineEndBAP != 0) {
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, false));
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
// extra elements representing a letter space that is suppressed
// if a break occurs
- if (widthIfNoBreakOccurs.min != 0
- || widthIfNoBreakOccurs.max != 0) {
- baseList
- .add(new KnuthGlue(widthIfNoBreakOccurs.opt
- - (this.lineStartBAP + this.lineEndBAP),
- widthIfNoBreakOccurs.max
- - widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.opt
- - widthIfNoBreakOccurs.min,
- this.auxiliaryPosition, false));
+ if (widthIfNoBreakOccurs.isNonZero()) {
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs.getOpt()
+ - (lineStartBAP + lineEndBAP),
+ widthIfNoBreakOccurs.getStretch(),
+ widthIfNoBreakOccurs.getShrink(),
+ auxiliaryPosition, false));
} else {
- baseList.add(new KnuthGlue(-(this.lineStartBAP + this.lineEndBAP), 0, 0,
- this.auxiliaryPosition, false));
+ baseList.add(new KnuthGlue(-(lineStartBAP + lineEndBAP), 0, 0,
+ auxiliaryPosition, false));
}
- baseList.add(this.makeAuxiliaryZeroWidthBox());
- baseList.add(this.makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(this.lineStartBAP, 0, 0,
- this.auxiliaryPosition, false));
+ baseList.add(makeAuxiliaryZeroWidthBox());
+ baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
+ baseList.add(new KnuthGlue(lineStartBAP, 0, 0,
+ auxiliaryPosition, false));
} else {
baseList.add(new KnuthPenalty(widthIfBreakOccurs,
unflagged ? TextLayoutManager.SOFT_HYPHEN_PENALTY
: KnuthPenalty.FLAGGED_PENALTY, !unflagged,
- this.auxiliaryPosition, false));
+ auxiliaryPosition, false));
// extra elements representing a letter space that is suppressed
// if a break occurs
- if (widthIfNoBreakOccurs.min != 0
- || widthIfNoBreakOccurs.max != 0) {
- baseList.add(new KnuthGlue(widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.max - widthIfNoBreakOccurs.opt,
- widthIfNoBreakOccurs.opt - widthIfNoBreakOccurs.min,
- this.auxiliaryPosition, false));
+ if (widthIfNoBreakOccurs.isNonZero()) {
+ baseList.add(new KnuthGlue(widthIfNoBreakOccurs, auxiliaryPosition, false));
}
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
index 97f07da54..4b93bcdac 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
@@ -28,8 +28,6 @@ import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.TraitSetter;
-import java.util.LinkedList;
-
/**
* This is the layout manager for the fo:wrapper formatting object.
*/
@@ -67,14 +65,14 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager {
public void addAreas(PositionIterator posIter, LayoutContext context) {
if (fobj.hasId()) {
addId();
- if (parentLM instanceof BlockStackingLayoutManager
- && !(parentLM instanceof BlockLayoutManager)) {
+ if (parentLayoutManager instanceof BlockStackingLayoutManager
+ && !(parentLayoutManager instanceof BlockLayoutManager)) {
Block helperBlock = new Block();
TraitSetter.setProducerID(helperBlock, fobj.getId());
- parentLM.addChildArea(helperBlock);
+ parentLayoutManager.addChildArea(helperBlock);
} else {
InlineArea area = getEffectiveArea();
- parentLM.addChildArea(area);
+ parentLayoutManager.addChildArea(area);
}
}
while (posIter.hasNext()) {
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index a9f2eeb27..8ab79d2c4 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -154,7 +154,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager
// if this will create the first block area in a page
// and display-align is after or center, add space before
if (layoutContext.getSpaceBefore() > 0) {
- addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
+ addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
addId();
@@ -241,7 +241,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager
// Set up dimensions
// Must get dimensions from parent area
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
// set traits
TraitSetter.setProducerID(curBlockArea, getListBlockFO().getId());
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
index 7fd2219ea..246c57094 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
@@ -201,7 +201,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager {
TraitSetter.setProducerID(curBlockArea, getPartFO().getId());
// Set up dimensions
- Area parentArea = parentLM.getParentArea(curBlockArea);
+ Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index 9848584c0..206d0ae1c 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -604,7 +604,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
curBlockArea = new Block();
// Set up dimensions
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
// set traits
TraitSetter.setProducerID(curBlockArea, getListItemFO().getId());
diff --git a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
index abcde41c7..36d42dbbe 100644
--- a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
+++ b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
@@ -38,7 +38,6 @@ import org.apache.fop.layoutmgr.KnuthBlockBox;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthPenalty;
-import org.apache.fop.layoutmgr.MinOptMaxUtil;
import org.apache.fop.traits.MinOptMax;
/**
@@ -211,8 +210,7 @@ class ActiveCell {
bpAfterNormal = paddingAfterNormal + pgu.getAfterBorderWidth(ConditionalBorder.NORMAL);
bpAfterTrailing = paddingAfterTrailing + pgu.getAfterBorderWidth(0, ConditionalBorder.REST);
elementList = pgu.getElements();
- handleExplicitHeight(
- MinOptMaxUtil.toMinOptMax(pgu.getCell().getBlockProgressionDimension(), tableLM),
+ handleExplicitHeight(pgu.getCell().getBlockProgressionDimension().toMinOptMax(tableLM),
row.getExplicitHeight());
knuthIter = elementList.listIterator();
includedLength = -1; // Avoid troubles with cells having content of zero length
@@ -239,7 +237,7 @@ class ActiveCell {
* occurs. The list of elements needs to be re-adjusted after each break.
*/
private void handleExplicitHeight(MinOptMax cellBPD, MinOptMax rowBPD) {
- int minBPD = Math.max(cellBPD.min, rowBPD.min);
+ int minBPD = Math.max(cellBPD.getMin(), rowBPD.getMin());
if (minBPD > 0) {
ListIterator iter = elementList.listIterator();
int cumulateLength = 0;
@@ -264,7 +262,7 @@ class ActiveCell {
}
}
}
- int optBPD = Math.max(minBPD, Math.max(cellBPD.opt, rowBPD.opt));
+ int optBPD = Math.max(minBPD, Math.max(cellBPD.getOpt(), rowBPD.getOpt()));
if (pgu.getContentLength() < optBPD) {
elementList.add(new FillerBox(optBPD - pgu.getContentLength()));
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
index 83e71bb21..7c11db17d 100644
--- a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
@@ -35,7 +35,6 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.MinOptMaxUtil;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.BreakUtil;
@@ -43,6 +42,8 @@ class RowGroupLayoutManager {
private static Log log = LogFactory.getLog(RowGroupLayoutManager.class);
+ private static final MinOptMax MAX_STRETCH = MinOptMax.getInstance(0, 0, Integer.MAX_VALUE);
+
private EffRow[] rowGroup;
private TableLayoutManager tableLM;
@@ -146,12 +147,12 @@ class RowGroupLayoutManager {
MinOptMax explicitRowHeight;
TableRow tableRowFO = rowGroup[rgi].getTableRow();
if (tableRowFO == null) {
- rowHeights[rgi] = new MinOptMax(0, 0, Integer.MAX_VALUE);
- explicitRowHeight = new MinOptMax(0, 0, Integer.MAX_VALUE);
+ rowHeights[rgi] = MAX_STRETCH;
+ explicitRowHeight = MAX_STRETCH;
} else {
LengthRangeProperty rowBPD = tableRowFO.getBlockProgressionDimension();
- rowHeights[rgi] = MinOptMaxUtil.toMinOptMax(rowBPD, tableLM);
- explicitRowHeight = MinOptMaxUtil.toMinOptMax(rowBPD, tableLM);
+ rowHeights[rgi] = rowBPD.toMinOptMax(tableLM);
+ explicitRowHeight = rowBPD.toMinOptMax(tableLM);
}
for (Iterator iter = row.getGridUnits().iterator(); iter.hasNext();) {
GridUnit gu = (GridUnit) iter.next();
@@ -168,7 +169,7 @@ class RowGroupLayoutManager {
.getValue(tableLM);
}
if (gu.getRowSpanIndex() == 0) {
- effectiveCellBPD = Math.max(effectiveCellBPD, explicitRowHeight.opt);
+ effectiveCellBPD = Math.max(effectiveCellBPD, explicitRowHeight.getOpt());
}
effectiveCellBPD = Math.max(effectiveCellBPD, primary.getContentLength());
int borderWidths = primary.getBeforeAfterBorderWidth();
@@ -179,11 +180,11 @@ class RowGroupLayoutManager {
padding += cbpb.getPaddingAfter(false, primary.getCellLM());
int effRowHeight = effectiveCellBPD + padding + borderWidths;
for (int prev = rgi - 1; prev >= rgi - gu.getRowSpanIndex(); prev--) {
- effRowHeight -= rowHeights[prev].opt;
+ effRowHeight -= rowHeights[prev].getOpt();
}
- if (effRowHeight > rowHeights[rgi].min) {
+ if (effRowHeight > rowHeights[rgi].getMin()) {
// This is the new height of the (grid) row
- MinOptMaxUtil.extendMinimum(rowHeights[rgi], effRowHeight);
+ rowHeights[rgi] = rowHeights[rgi].extendMinimum(effRowHeight);
}
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
index edf73acab..e28126c3e 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
@@ -181,7 +181,7 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
- Area parentArea = parentLM.getParentArea(curBlockArea);
+ Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
index 9d9255e0c..c7d0d0da4 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
@@ -177,7 +177,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager {
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
- Area parentArea = parentLM.getParentArea(curBlockArea);
+ Area parentArea = parentLayoutManager.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
index ea2e64afb..0599b430c 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
@@ -131,7 +131,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
* {@inheritDoc}
*/
public List getNextKnuthElements(LayoutContext context, int alignment) {
- MinOptMax stackLimit = new MinOptMax(context.getStackLimitBP());
+ MinOptMax stackLimit = context.getStackLimitBP();
referenceIPD = context.getRefIPD();
cellIPD = referenceIPD;
@@ -146,8 +146,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
while ((curLM = getChildLM()) != null) {
LayoutContext childLC = new LayoutContext(0);
// curLM is a ?
- childLC.setStackLimitBP(MinOptMax.subtract(context
- .getStackLimitBP(), stackLimit));
+ childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
childLC.setRefIPD(cellIPD);
// get elements from curLM
@@ -387,7 +386,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
adjustXOffset(block, dx);
adjustIPD(block, ipd);
adjustBPD(block, bpd);
- parentLM.addChildArea(block);
+ parentLayoutManager.addChildArea(block);
}
dx += ipd;
}
@@ -439,8 +438,8 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
TableColumn column = getTable().getColumn(primaryGridUnit.getColIndex());
if (column.getCommonBorderPaddingBackground().hasBackground()) {
Block colBackgroundArea = getBackgroundArea(paddingRectBPD, borderBeforeWidth);
- ((TableLayoutManager) parentLM).registerColumnBackgroundArea(column, colBackgroundArea,
- -startIndent);
+ ((TableLayoutManager) parentLayoutManager).registerColumnBackgroundArea(column,
+ colBackgroundArea, -startIndent);
}
TablePart body = primaryGridUnit.getTablePart();
@@ -452,11 +451,11 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
TableRow row = primaryGridUnit.getRow();
if (row != null && row.getCommonBorderPaddingBackground().hasBackground()) {
Block rowBackgroundArea = getBackgroundArea(paddingRectBPD, borderBeforeWidth);
- ((TableLayoutManager) parentLM).addBackgroundArea(rowBackgroundArea);
+ ((TableLayoutManager) parentLayoutManager).addBackgroundArea(rowBackgroundArea);
TraitSetter.addBackground(rowBackgroundArea, row.getCommonBorderPaddingBackground(),
- parentLM,
+ parentLayoutManager,
-xoffset - startIndent, -borderBeforeWidth,
- parentLM.getContentAreaIPD(), firstRowHeight);
+ parentLayoutManager.getContentAreaIPD(), firstRowHeight);
}
}
@@ -526,7 +525,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
curBlockArea.setYOffset(yoffset);
curBlockArea.setIPD(cellIPD);
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 9ccca8b9e..e12839b0b 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -327,7 +327,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
// add space before, in order to implement display-align = "center" or "after"
if (layoutContext.getSpaceBefore() != 0) {
- addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
+ addBlockSpacing(0.0, MinOptMax.getInstance(layoutContext.getSpaceBefore()));
}
int startXOffset = getTable().getCommonMarginBlock().startIndent.getValue(this);
@@ -404,7 +404,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
- /*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
+ /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea);
TraitSetter.setProducerID(curBlockArea, getTable().getId());
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
index 92a641ed0..92e8ba5dd 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
@@ -122,7 +122,7 @@ public class TableStepper {
private void calcTotalHeight() {
totalHeight = 0;
for (int i = 0; i < rowGroup.length; i++) {
- totalHeight += rowGroup[i].getHeight().opt;
+ totalHeight += rowGroup[i].getHeight().getOpt();
}
if (log.isDebugEnabled()) {
log.debug("totalHeight=" + totalHeight);
@@ -137,12 +137,12 @@ public class TableStepper {
PrimaryGridUnit pgu = activeCell.getPrimaryGridUnit();
for (int i = activeRowIndex + 1; i < pgu.getRowIndex() - rowGroup[0].getIndex()
+ pgu.getCell().getNumberRowsSpanned(); i++) {
- remain -= rowGroup[i].getHeight().opt;
+ remain -= rowGroup[i].getHeight().getOpt();
}
maxW = Math.max(maxW, remain);
}
for (int i = activeRowIndex + 1; i < rowGroup.length; i++) {
- maxW += rowGroup[i].getHeight().opt;
+ maxW += rowGroup[i].getHeight().getOpt();
}
return maxW;
}
@@ -315,7 +315,7 @@ public class TableStepper {
if (delayingNextRow) {
int minStep = computeMinStep();
if (minStep < 0 || minStep >= rowFirstStep
- || minStep > rowGroup[activeRowIndex].getExplicitHeight().max) {
+ || minStep > rowGroup[activeRowIndex].getExplicitHeight().getMax()) {
if (log.isTraceEnabled()) {
log.trace("Step = " + minStep);
}
@@ -462,7 +462,7 @@ public class TableStepper {
*/
private void prepareNextRow() {
if (activeRowIndex < rowGroup.length - 1) {
- previousRowsLength += rowGroup[activeRowIndex].getHeight().opt;
+ previousRowsLength += rowGroup[activeRowIndex].getHeight().getOpt();
activateCells(nextActiveCells, activeRowIndex + 1);
if (log.isTraceEnabled()) {
log.trace("Computing first step for row " + (activeRowIndex + 2));
diff --git a/src/java/org/apache/fop/traits/MinOptMax.java b/src/java/org/apache/fop/traits/MinOptMax.java
index a4719f896..0f0422799 100644
--- a/src/java/org/apache/fop/traits/MinOptMax.java
+++ b/src/java/org/apache/fop/traits/MinOptMax.java
@@ -19,175 +19,326 @@
package org.apache.fop.traits;
+import java.io.Serializable;
+
+import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.apache.fop.fo.properties.SpaceProperty;
+
/**
- * This class holds the resolved (as mpoints) form of a LengthRange or
- * Space type Property value.
- * MinOptMax values are used during layout calculations. The instance
- * variables are package visible.
+ * This class holds the resolved (as mpoints) form of a {@link LengthRangeProperty LengthRange} or
+ * {@link SpaceProperty Space} type property value.
+ * <p/>
+ * Instances of this class are immutable. All arithmetic methods like {@link #plus(MinOptMax) plus},
+ * {@link #minus(MinOptMax) minus} or {@link #mult(int) mult} return a different instance. So it is
+ * possible to pass around instances without copying.
+ * <p/>
+ * <code>MinOptMax</code> values are used during layout calculations.
*/
-public class MinOptMax implements java.io.Serializable, Cloneable {
+public final class MinOptMax implements Serializable {
- /** Publicly visible min(imum), opt(imum) and max(imum) values.*/
- public int min;
- public int opt;
- public int max;
+ private static final long serialVersionUID = -4791524475122206142L;
/**
- * New min/opt/max with zero values.
+ * The zero <code>MinOptMax</code> instance with <code>min == opt == max == 0</code>.
*/
- public MinOptMax() {
- this(0);
- }
+ public static final MinOptMax ZERO = getInstance(0);
+
+ private final int min;
+ private final int opt;
+ private final int max;
/**
- * New min/opt/max with one fixed value.
+ * Returns an instance of <code>MinOptMax</code> with the given values.
*
- * @param val the value for min, opt and max
+ * @param min the minimum value
+ * @param opt the optimum value
+ * @param max the maximum value
+ * @return the corresponding instance
+ * @throws IllegalArgumentException if <code>min > opt || max < opt</code>.
*/
- public MinOptMax(int val) {
- this(val, val, val);
+ public static MinOptMax getInstance(int min, int opt, int max) {
+ if (min > opt) {
+ throw new IllegalArgumentException("min (" + min + ") > opt (" + opt + ")");
+ }
+ if (max < opt) {
+ throw new IllegalArgumentException("max (" + max + ") < opt (" + opt + ")");
+ }
+ return new MinOptMax(min, opt, max);
}
/**
- * New min/opt/max with the three values.
+ * Returns an instance of <code>MinOptMax</code> with one fixed value for all three
+ * properties (min, opt, max).
*
- * @param min the minimum value
- * @param opt the optimum value
- * @param max the maximum value
+ * @param value the value for min, opt and max
+ * @return the corresponding instance
+ * @see #isStiff()
*/
- public MinOptMax(int min, int opt, int max) {
- // TODO: assert min<=opt<=max
+ public static MinOptMax getInstance(int value) {
+ return new MinOptMax(value, value, value);
+ }
+
+ // Private constructor without consistency checks
+ private MinOptMax(int min, int opt, int max) {
+ assert min <= opt && opt <= max;
this.min = min;
this.opt = opt;
this.max = max;
}
/**
- * Copy constructor.
+ * Returns the minimum value of this <code>MinOptMax</code>.
*
- * @param op the MinOptMax object to copy
+ * @return the minimum value of this <code>MinOptMax</code>.
*/
- public MinOptMax(MinOptMax op) {
- this.min = op.min;
- this.opt = op.opt;
- this.max = op.max;
+ public int getMin() {
+ return min;
}
- // TODO: remove this.
/**
- * {@inheritDoc}
+ * Returns the optimum value of this <code>MinOptMax</code>.
+ *
+ * @return the optimum value of this <code>MinOptMax</code>.
*/
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException ex) {
- // SHOULD NEVER OCCUR - all members are primitive types!
- return null;
- }
+ public int getOpt() {
+ return opt;
+ }
+
+ /**
+ * Returns the maximum value of this <code>MinOptMax</code>.
+ *
+ * @return the maximum value of this <code>MinOptMax</code>.
+ */
+ public int getMax() {
+ return max;
}
/**
- * Subtracts one MinOptMax instance from another returning a new one.
- * @param op1 first instance to subtract from
- * @param op2 second instance
- * @return MinOptMax new instance
+ * Returns the shrinkability of this <code>MinOptMax</code> which is the absolute difference
+ * between <code>min</code> and <code>opt</code>.
+ *
+ * @return the shrinkability of this <code>MinOptMax</code> which is always non-negative.
*/
- public static MinOptMax subtract(MinOptMax op1, MinOptMax op2) {
- return new MinOptMax(op1.min - op2.max, op1.opt - op2.opt,
- op1.max - op2.min);
+ public int getShrink() {
+ return opt - min;
}
/**
- * Adds one MinOptMax instance to another returning a new one.
- * @param op1 first instance
- * @param op2 second instance
- * @return MinOptMax new instance
+ * Returns the stretchability of this <code>MinOptMax</code> which is the absolute difference
+ * between <code>opt</code> and <code>max</code>.
+ *
+ * @return the stretchability of this <code>MinOptMax</code> which is always non-negative.
*/
- public static MinOptMax add(MinOptMax op1, MinOptMax op2) {
- return new MinOptMax(op1.min + op2.min, op1.opt + op2.opt,
- op1.max + op2.max);
+ public int getStretch() {
+ return max - opt;
}
/**
- * Multiplies a MinOptMax instance with a factor returning a new instance.
- * @param op1 MinOptMax instance
- * @param mult multiplier
- * @return MinOptMax new instance
+ * Returns the sum of this <code>MinOptMax</code> and the given <code>MinOptMax</code>.
+ *
+ * @param operand the second operand of the sum (the first is this instance itself),
+ * @return the sum of this <code>MinOptMax</code> and the given <code>MinOptMax</code>.
*/
- public static MinOptMax multiply(MinOptMax op1, double mult) {
- // TODO: assert mult>0
- return new MinOptMax((int)(op1.min * mult),
- (int)(op1.opt * mult), (int)(op1.max * mult));
+ public MinOptMax plus(MinOptMax operand) {
+ return new MinOptMax(min + operand.min, opt + operand.opt, max + operand.max);
}
+
/**
- * Adds another MinOptMax instance to this one.
- * @param op the other instance
+ * Adds the given value to all three components of this instance and returns the result.
+ *
+ * @param value value to add to the min, opt, max components
+ * @return the result of the addition
*/
- public void add(MinOptMax op) {
- min += op.min;
- opt += op.opt;
- max += op.max;
+ public MinOptMax plus(int value) {
+ return new MinOptMax(min + value, opt + value, max + value);
+ }
+
+ /**
+ * Returns the difference of this <code>MinOptMax</code> and the given
+ * <code>MinOptMax</code>. This instance must be a compound of the operand and another
+ * <code>MinOptMax</code>, that is, there must exist a <code>MinOptMax</code> <i>m</i>
+ * such that <code>this.equals(m.plus(operand))</code>. In other words, the operand
+ * must have less shrink and stretch than this instance.
+ *
+ * @param operand the value to be subtracted
+ * @return the difference of this <code>MinOptMax</code> and the given
+ * <code>MinOptMax</code>.
+ * @throws ArithmeticException if this instance has strictly less shrink or stretch
+ * than the operand
+ */
+ public MinOptMax minus(MinOptMax operand) {
+ checkCompatibility(getShrink(), operand.getShrink(), "shrink");
+ checkCompatibility(getStretch(), operand.getStretch(), "stretch");
+ return new MinOptMax(min - operand.min, opt - operand.opt, max - operand.max);
+ }
+
+ private void checkCompatibility(int thisElasticity, int operandElasticity, String msge) {
+ if (thisElasticity < operandElasticity) {
+ throw new ArithmeticException(
+ "Cannot subtract a MinOptMax from another MinOptMax that has less " + msge
+ + " (" + thisElasticity + " < " + operandElasticity + ")");
+ }
}
/**
- * Adds min, opt and max to their counterpart components.
- * @param min the value to add to the minimum value
- * @param opt the value to add to the optimum value
- * @param max the value to add to the maximum value
+ * Subtracts the given value from all three components of this instance and returns the result.
+ *
+ * @param value value to subtract from the min, opt, max components
+ * @return the result of the subtraction
*/
- public void add(int min, int opt, int max) {
- this.min += min;
- this.opt += opt;
- this.max += max;
- // TODO: assert min<=opt<=max
+ public MinOptMax minus(int value) {
+ return new MinOptMax(min - value, opt - value, max - value);
}
/**
- * Adds a length to all components.
- * @param len the length to add
+ * Returns an instance with the given value added to the minimal value.
+ *
+ * @param minOperand the minimal value to be added.
+ * @return an instance with the given value added to the minimal value.
+ * @throws IllegalArgumentException if <code>min + minOperand > opt || max < opt</code>.
+ * @deprecated Do not use! It's only for backwards compatibility.
*/
- public void add(int len) {
- this.min += len;
- this.opt += len;
- this.max += len;
+ public MinOptMax plusMin(int minOperand) {
+ return getInstance(min + minOperand, opt, max);
}
+ /**
+ * Returns an instance with the given value subtracted to the minimal value.
+ *
+ * @param minOperand the minimal value to be subtracted.
+ * @return an instance with the given value subtracted to the minimal value.
+ * @throws IllegalArgumentException if <code>min - minOperand > opt || max < opt</code>.
+ * @deprecated Do not use! It's only for backwards compatibility.
+ */
+ public MinOptMax minusMin(int minOperand) {
+ return getInstance(min - minOperand, opt, max);
+ }
/**
- * Subtracts another MinOptMax instance from this one.
- * @param op the other instance
+ * Returns an instance with the given value added to the maximal value.
+ *
+ * @param maxOperand the maximal value to be added.
+ * @return an instance with the given value added to the maximal value.
+ * @throws IllegalArgumentException if <code>min > opt || max < opt + maxOperand</code>.
+ * @deprecated Do not use! It's only for backwards compatibility.
*/
- public void subtract(MinOptMax op) {
- min -= op.max;
- opt -= op.opt;
- max -= op.min;
+ public MinOptMax plusMax(int maxOperand) {
+ return getInstance(min, opt, max + maxOperand);
}
- /** @return true if this instance represents a zero-width length (min=opt=max=0) */
+ /**
+ * Returns an instance with the given value subtracted to the maximal value.
+ *
+ * @param maxOperand the maximal value to be subtracted.
+ * @return an instance with the given value subtracted to the maximal value.
+ * @throws IllegalArgumentException if <code>min > opt || max < opt - maxOperand</code>.
+ * @deprecated Do not use! It's only for backwards compatibility.
+ */
+ public MinOptMax minusMax(int maxOperand) {
+ return getInstance(min, opt, max - maxOperand);
+ }
+
+ /**
+ * Returns the product of this <code>MinOptMax</code> and the given factor.
+ *
+ * @param factor the factor
+ * @return the product of this <code>MinOptMax</code> and the given factor
+ * @throws IllegalArgumentException if the factor is negative
+ */
+ public MinOptMax mult(int factor) {
+ if (factor < 0) {
+ throw new IllegalArgumentException("factor < 0; was: " + factor);
+ } else if (factor == 1) {
+ return this;
+ } else {
+ return getInstance(min * factor, opt * factor, max * factor);
+ }
+ }
+
+ /**
+ * Determines whether this <code>MinOptMax</code> represents a non-zero dimension, which means
+ * that not all values (min, opt, max) are zero.
+ *
+ * @return <code>true</code> if this <code>MinOptMax</code> represents a non-zero dimension;
+ * <code>false</code> otherwise.
+ */
public boolean isNonZero() {
- return (min != 0 || max != 0);
+ return min != 0 || max != 0;
+ }
+
+ /**
+ * Determines whether this <code>MinOptMax</code> doesn't allow for shrinking or stretching,
+ * which means that all values (min, opt, max) are the same.
+ *
+ * @return <code>true</code> if whether this <code>MinOptMax</code> doesn't allow for shrinking
+ * or stretching; <code>false</code> otherwise.
+ * @see #isElastic()
+ */
+ public boolean isStiff() {
+ return min == max;
}
- /** @return true if this instance allows for shrinking or stretching */
+ /**
+ * Determines whether this <code>MinOptMax</code> allows for shrinking or stretching, which
+ * means that at least one of the min or max values isn't equal to the opt value.
+ *
+ * @return <code>true</code> if this <code>MinOptMax</code> allows for shrinking or stretching;
+ * <code>false</code> otherwise.
+ * @see #isStiff()
+ */
public boolean isElastic() {
- return (min != opt || opt != max);
+ return min != opt || opt != max;
}
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("MinOptMax[min=");
- if (min != opt) {
- sb.append(min).append("; ");
+ /**
+ * Extends the minimum length to the given length if necessary, and adjusts opt and max
+ * accordingly.
+ *
+ * @param newMin the new minimum length
+ * @return a <code>MinOptMax</code> instance with the minimum length extended
+ */
+ public MinOptMax extendMinimum(int newMin) {
+ if (min < newMin) {
+ int newOpt = Math.max(newMin, opt);
+ int newMax = Math.max(newOpt, max);
+ return getInstance(newMin, newOpt, newMax);
+ } else {
+ return this;
}
- sb.append("opt=");
- if (opt != max) {
- sb.append(opt).append("; ");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
}
- sb.append("max=").append(max);
- sb.append("]");
- return sb.toString();
+
+ MinOptMax minOptMax = (MinOptMax) obj;
+
+ return opt == minOptMax.opt && max == minOptMax.max && min == minOptMax.min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ int result = min;
+ result = 31 * result + opt;
+ result = 31 * result + max;
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "MinOptMax[min = " + min + ", opt = " + opt + ", max = " + max + "]";
}
}
diff --git a/src/java/org/apache/fop/traits/SpaceVal.java b/src/java/org/apache/fop/traits/SpaceVal.java
index e2ac6fb1c..cb709c73e 100644
--- a/src/java/org/apache/fop/traits/SpaceVal.java
+++ b/src/java/org/apache/fop/traits/SpaceVal.java
@@ -32,9 +32,9 @@ import org.apache.fop.fonts.Font;
public class SpaceVal {
private final MinOptMax space;
- private final boolean bConditional;
- private final boolean bForcing;
- private final int iPrecedence; // Numeric only, if forcing, set to 0
+ private final boolean conditional;
+ private final boolean forcing;
+ private final int precedence; // Numeric only, if forcing, set to 0
/**
* Constructor for SpaceVal objects based on Space objects.
@@ -42,21 +42,26 @@ public class SpaceVal {
* @param context Percentage evaluation context
*/
public SpaceVal(SpaceProperty spaceprop, PercentBaseContext context) {
- space = new MinOptMax(spaceprop.getMinimum(context).getLength().getValue(context),
- spaceprop.getOptimum(context).getLength().getValue(context),
- spaceprop.getMaximum(context).getLength().getValue(context));
- bConditional =
- (spaceprop.getConditionality().getEnum() == Constants.EN_DISCARD);
+ space = createSpaceProperty(spaceprop, context);
+ conditional = (spaceprop.getConditionality().getEnum() == Constants.EN_DISCARD);
Property precProp = spaceprop.getPrecedence();
if (precProp.getNumber() != null) {
- iPrecedence = precProp.getNumber().intValue();
- bForcing = false;
+ precedence = precProp.getNumber().intValue();
+ forcing = false;
} else {
- bForcing = (precProp.getEnum() == Constants.EN_FORCE);
- iPrecedence = 0;
+ forcing = (precProp.getEnum() == Constants.EN_FORCE);
+ precedence = 0;
}
}
+ private static MinOptMax createSpaceProperty(SpaceProperty spaceprop,
+ PercentBaseContext context) {
+ int min = spaceprop.getMinimum(context).getLength().getValue(context);
+ int opt = spaceprop.getOptimum(context).getLength().getValue(context);
+ int max = spaceprop.getMaximum(context).getLength().getValue(context);
+ return MinOptMax.getInstance(min, opt, max);
+ }
+
/**
* Constructor for SpaceVal objects based on the full set of properties.
* @param space space to use
@@ -64,36 +69,30 @@ public class SpaceVal {
* @param bForcing Forcing value
* @param iPrecedence Precedence value
*/
- public SpaceVal(MinOptMax space, boolean bConditional,
- boolean bForcing, int iPrecedence) {
+ public SpaceVal(MinOptMax space, boolean conditional, boolean forcing, int precedence) {
this.space = space;
- this.bConditional = bConditional;
- this.bForcing = bForcing;
- this.iPrecedence = iPrecedence;
+ this.conditional = conditional;
+ this.forcing = forcing;
+ this.precedence = precedence;
}
- static public SpaceVal makeWordSpacing(Property wordSpacing,
- SpaceVal letterSpacing,
- Font fs) {
+ public static SpaceVal makeWordSpacing(Property wordSpacing, SpaceVal letterSpacing, Font fs) {
if (wordSpacing.getEnum() == Constants.EN_NORMAL) {
// give word spaces the possibility to shrink by a third,
// and stretch by a half;
int spaceCharIPD = fs.getCharWidth(' ');
- MinOptMax space = new MinOptMax(-spaceCharIPD / 3, 0, spaceCharIPD / 2);
+ MinOptMax space = MinOptMax.getInstance(-spaceCharIPD / 3, 0, spaceCharIPD / 2);
//TODO Adding 2 letter spaces here is not 100% correct. Spaces don't have letter spacing
- return new SpaceVal(
- MinOptMax.add
- (space, MinOptMax.multiply(letterSpacing.getSpace(), 2)),
- true, true, 0);
+ return new SpaceVal(space.plus(letterSpacing.getSpace().mult(2)), true, true, 0);
} else {
return new SpaceVal(wordSpacing.getSpace(), null);
}
}
- static public SpaceVal makeLetterSpacing(Property letterSpacing) {
+ public static SpaceVal makeLetterSpacing(Property letterSpacing) {
if (letterSpacing.getEnum() == Constants.EN_NORMAL) {
// letter spaces are set to zero (or use different values?)
- return new SpaceVal(new MinOptMax(0), true, true, 0);
+ return new SpaceVal(MinOptMax.ZERO, true, true, 0);
} else {
return new SpaceVal(letterSpacing.getSpace(), null);
}
@@ -104,7 +103,7 @@ public class SpaceVal {
* @return the Conditionality value
*/
public boolean isConditional() {
- return bConditional;
+ return conditional;
}
/**
@@ -112,7 +111,7 @@ public class SpaceVal {
* @return the Forcing value
*/
public boolean isForcing() {
- return bForcing;
+ return forcing;
}
/**
@@ -120,7 +119,7 @@ public class SpaceVal {
* @return the Precedence value
*/
public int getPrecedence() {
- return iPrecedence;
+ return precedence;
}
/**
@@ -131,6 +130,7 @@ public class SpaceVal {
return space;
}
+ /** {@inheritDoc} */
public String toString() {
return "SpaceVal: " + getSpace().toString();
}
diff --git a/test/java/org/apache/fop/StandardTestSuite.java b/test/java/org/apache/fop/StandardTestSuite.java
index 250ddaad6..281301789 100644
--- a/test/java/org/apache/fop/StandardTestSuite.java
+++ b/test/java/org/apache/fop/StandardTestSuite.java
@@ -34,6 +34,7 @@ import org.apache.fop.render.pdf.PDFCMapTestCase;
import org.apache.fop.render.pdf.PDFEncodingTestCase;
import org.apache.fop.render.pdf.PDFsRGBSettingsTestCase;
import org.apache.fop.render.rtf.RichTextFormatTestSuite;
+import org.apache.fop.traits.MinOptMaxTest;
/**
* Test suite for basic functionality of FOP.
@@ -45,8 +46,7 @@ public class StandardTestSuite {
* @return the test suite
*/
public static Test suite() {
- TestSuite suite = new TestSuite(
- "Basic functionality test suite for FOP");
+ TestSuite suite = new TestSuite("Basic functionality test suite for FOP");
//$JUnit-BEGIN$
suite.addTest(BasicDriverTestSuite.suite());
suite.addTest(UtilityCodeTestSuite.suite());
@@ -62,6 +62,7 @@ public class StandardTestSuite {
suite.addTest(new TestSuite(IFMimickingTestCase.class));
suite.addTest(new TestSuite(PageBoundariesTest.class));
suite.addTest(new TestSuite(PageScaleTest.class));
+ suite.addTest(new TestSuite(MinOptMaxTest.class));
//$JUnit-END$
return suite;
}
diff --git a/test/java/org/apache/fop/traits/MinOptMaxTest.java b/test/java/org/apache/fop/traits/MinOptMaxTest.java
new file mode 100644
index 000000000..17f46b7b0
--- /dev/null
+++ b/test/java/org/apache/fop/traits/MinOptMaxTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.traits;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the {@link MinOptMaxTest} class.
+ */
+public class MinOptMaxTest extends TestCase {
+
+ /**
+ * Tests that the constant <code>MinOptMax.ZERO</code> is really zero.
+ */
+ public void testZero() {
+ assertEquals(MinOptMax.getInstance(0), MinOptMax.ZERO);
+ }
+
+ public void testNewStiffMinOptMax() {
+ MinOptMax value = MinOptMax.getInstance(1);
+ assertTrue(value.isStiff());
+ assertEquals(1, value.getMin());
+ assertEquals(1, value.getOpt());
+ assertEquals(1, value.getMax());
+ }
+
+ public void testNewMinOptMax() {
+ MinOptMax value = MinOptMax.getInstance(1, 2, 3);
+ assertTrue(value.isElastic());
+ assertEquals(1, value.getMin());
+ assertEquals(2, value.getOpt());
+ assertEquals(3, value.getMax());
+ }
+
+ /**
+ * Test that it is possible to create stiff instances with the normal factory method.
+ */
+ public void testNewMinOptMaxStiff() {
+ MinOptMax value = MinOptMax.getInstance(1, 1, 1);
+ assertTrue(value.isStiff());
+ assertEquals(1, value.getMin());
+ assertEquals(1, value.getOpt());
+ assertEquals(1, value.getMax());
+ }
+
+ public void testNewMinOptMaxMinGreaterOpt() {
+ try {
+ MinOptMax.getInstance(1, 0, 2);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("min (1) > opt (0)", e.getMessage());
+ }
+ }
+
+ public void testNewMinOptMaxMaxSmallerOpt() {
+ try {
+ MinOptMax.getInstance(0, 1, 0);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("max (0) < opt (1)", e.getMessage());
+ }
+ }
+
+ public void testShrinkablility() {
+ assertEquals(0, MinOptMax.getInstance(1).getShrink());
+ assertEquals(1, MinOptMax.getInstance(1, 2, 2).getShrink());
+ assertEquals(2, MinOptMax.getInstance(1, 3, 3).getShrink());
+ }
+
+ public void testStrechablilty() {
+ assertEquals(0, MinOptMax.getInstance(1).getStretch());
+ assertEquals(1, MinOptMax.getInstance(1, 1, 2).getStretch());
+ assertEquals(2, MinOptMax.getInstance(1, 1, 3).getStretch());
+ }
+
+ public void testPlus() {
+ assertEquals(MinOptMax.ZERO,
+ MinOptMax.ZERO.plus(MinOptMax.ZERO));
+ assertEquals(MinOptMax.getInstance(1, 2, 3),
+ MinOptMax.ZERO.plus(MinOptMax.getInstance(1, 2, 3)));
+ assertEquals(MinOptMax.getInstance(2, 4, 6),
+ MinOptMax.getInstance(1, 2, 3).plus(MinOptMax.getInstance(1, 2, 3)));
+ assertEquals(MinOptMax.getInstance(4, 5, 6), MinOptMax.getInstance(1, 2, 3).plus(3));
+ }
+
+ public void testMinus() {
+ assertEquals(MinOptMax.ZERO,
+ MinOptMax.ZERO.minus(MinOptMax.ZERO));
+ assertEquals(MinOptMax.getInstance(1, 2, 3),
+ MinOptMax.getInstance(1, 2, 3).plus(MinOptMax.ZERO));
+ assertEquals(MinOptMax.getInstance(1, 2, 3),
+ MinOptMax.getInstance(2, 4, 6).minus(MinOptMax.getInstance(1, 2, 3)));
+ assertEquals(MinOptMax.getInstance(1, 2, 3), MinOptMax.getInstance(5, 6, 7).minus(4));
+ }
+
+ public void testMinusFail1() {
+ try {
+ MinOptMax.ZERO.minus(MinOptMax.getInstance(1, 2, 3));
+ fail();
+ } catch (ArithmeticException e) {
+ // Ok
+ }
+ }
+
+ public void testMinusFail2() {
+ try {
+ MinOptMax.getInstance(1, 2, 3).minus(MinOptMax.getInstance(1, 3, 3));
+ fail();
+ } catch (ArithmeticException e) {
+ // Ok
+ }
+ }
+
+ public void testMinusFail3() {
+ try {
+ MinOptMax.ZERO.minus(MinOptMax.getInstance(1, 1, 2));
+ fail();
+ } catch (ArithmeticException e) {
+ // Ok
+ }
+ }
+
+ public void testMinusFail4() {
+ try {
+ MinOptMax.getInstance(1, 2, 3).minus(MinOptMax.getInstance(1, 1, 3));
+ fail();
+ } catch (ArithmeticException e) {
+ // Ok
+ }
+ }
+
+ public void testMult() {
+ assertEquals(MinOptMax.ZERO, MinOptMax.ZERO.mult(0));
+ assertEquals(MinOptMax.getInstance(1, 2, 3), MinOptMax.getInstance(1, 2, 3).mult(1));
+ assertEquals(MinOptMax.getInstance(2, 4, 6), MinOptMax.getInstance(1, 2, 3).mult(2));
+ }
+
+ public void testMultFail() {
+ try {
+ MinOptMax.getInstance(1, 2, 3).mult(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("factor < 0; was: -1", e.getMessage());
+ }
+ }
+
+ public void testNonZero() {
+ assertFalse(MinOptMax.ZERO.isNonZero());
+ assertTrue(MinOptMax.getInstance(1).isNonZero());
+ assertTrue(MinOptMax.getInstance(1, 2, 3).isNonZero());
+ }
+
+ public void testExtendMinimum() {
+ assertEquals(MinOptMax.getInstance(1, 1, 1),
+ MinOptMax.ZERO.extendMinimum(1));
+ assertEquals(MinOptMax.getInstance(1, 2, 3),
+ MinOptMax.getInstance(1, 2, 3).extendMinimum(1));
+ assertEquals(MinOptMax.getInstance(2, 2, 3),
+ MinOptMax.getInstance(1, 2, 3).extendMinimum(2));
+ assertEquals(MinOptMax.getInstance(3, 3, 3),
+ MinOptMax.getInstance(1, 2, 3).extendMinimum(3));
+ assertEquals(MinOptMax.getInstance(4, 4, 4),
+ MinOptMax.getInstance(1, 2, 3).extendMinimum(4));
+ }
+
+ public void testEquals() {
+ MinOptMax number = MinOptMax.getInstance(1, 3, 5);
+ assertEquals(number, number);
+ assertEquals(number, MinOptMax.getInstance(1, 3, 5));
+ assertFalse(number.equals(MinOptMax.getInstance(2, 3, 5)));
+ assertFalse(number.equals(MinOptMax.getInstance(1, 4, 5)));
+ assertFalse(number.equals(MinOptMax.getInstance(1, 3, 4)));
+ assertFalse(number.equals(null));
+ assertFalse(number.equals(new Integer(1)));
+ }
+
+ public void testHashCode() {
+ MinOptMax number = MinOptMax.getInstance(1, 2, 3);
+ assertEquals(number.hashCode(), number.hashCode());
+ assertEquals(number.hashCode(), MinOptMax.getInstance(1, 2, 3).hashCode());
+ }
+}