Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -201,7 +201,7 @@ 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
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -604,7 +604,7 @@ curBlockArea = new Block(); // Set up dimensions - /*Area parentArea =*/ parentLM.getParentArea(curBlockArea); + /*Area parentArea =*/ parentLayoutManager.getParentArea(curBlockArea); // set traits TraitSetter.setProducerID(curBlockArea, getListItemFO().getId()); Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java Tue Dec 22 17:20:51 2009 @@ -38,7 +38,6 @@ 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 @@ 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 @@ * 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 @@ } } } - 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())); } Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -35,7 +35,6 @@ 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 @@ 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 @@ 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 @@ .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 @@ 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); } } } Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -181,7 +181,7 @@ 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 Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -177,7 +177,7 @@ 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 Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -131,7 +131,7 @@ * {...@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 @@ 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 @@ adjustXOffset(block, dx); adjustIPD(block, ipd); adjustBPD(block, bpd); - parentLM.addChildArea(block); + parentLayoutManager.addChildArea(block); } dx += ipd; } @@ -439,8 +438,8 @@ 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 @@ 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 @@ 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 } Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java Tue Dec 22 17:20:51 2009 @@ -327,7 +327,7 @@ // 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 @@ 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()); Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java Tue Dec 22 17:20:51 2009 @@ -122,7 +122,7 @@ 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 @@ 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 @@ 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 @@ */ 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)); Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/MinOptMax.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/MinOptMax.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/MinOptMax.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/MinOptMax.java Tue Dec 22 17:20:51 2009 @@ -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; } - /** @return true if this instance allows for shrinking or stretching */ + /** + * 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; + } + + /** + * 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} */ + /** + * 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; + } + } + + /** + * {...@inheritdoc} + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + 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() { - StringBuffer sb = new StringBuffer(); - sb.append("MinOptMax[min="); - if (min != opt) { - sb.append(min).append("; "); - } - sb.append("opt="); - if (opt != max) { - sb.append(opt).append("; "); - } - sb.append("max=").append(max); - sb.append("]"); - return sb.toString(); + return "MinOptMax[min = " + min + ", opt = " + opt + ", max = " + max + "]"; } } Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/SpaceVal.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/SpaceVal.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/SpaceVal.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/SpaceVal.java Tue Dec 22 17:20:51 2009 @@ -32,9 +32,9 @@ 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 @@ * @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 @@ * @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 @@ * @return the Conditionality value */ public boolean isConditional() { - return bConditional; + return conditional; } /** @@ -112,7 +111,7 @@ * @return the Forcing value */ public boolean isForcing() { - return bForcing; + return forcing; } /** @@ -120,7 +119,7 @@ * @return the Precedence value */ public int getPrecedence() { - return iPrecedence; + return precedence; } /** @@ -131,6 +130,7 @@ return space; } + /** {...@inheritdoc} */ public String toString() { return "SpaceVal: " + getSpace().toString(); } Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/StandardTestSuite.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/StandardTestSuite.java?rev=893238&r1=893237&r2=893238&view=diff ============================================================================== --- xmlgraphics/fop/trunk/test/java/org/apache/fop/StandardTestSuite.java (original) +++ xmlgraphics/fop/trunk/test/java/org/apache/fop/StandardTestSuite.java Tue Dec 22 17:20:51 2009 @@ -34,6 +34,7 @@ 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 @@ * @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 @@ 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; } Added: xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java?rev=893238&view=auto ============================================================================== --- xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java (added) +++ xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java Tue Dec 22 17:20:51 2009 @@ -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()); + } +} Propchange: xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/MinOptMaxTest.java ------------------------------------------------------------------------------ svn:keywords = Revision Id --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
