Browse Source

Support for percentages in property expression.

The different length properties all implement a Length interface
and all clients of the property subsystem must use the Length interface
when retrieving lengths.

The two different numerics (absolute and relative) both implement a
Numeric interface and all property calculations are done in terms of
the Numeric interface.

Lengths can be cast to numeric and can thus participate in expresions and
numerics can be cast to length (when dimension is 1) and can thus be used
as a length by the clients.

The call to Length.getValue() will cause relative lengths to be resolved
against their base length, and care must be taken to ensure that
getLength() is only called after all baselength has been assigned to the
FO elements.

PR: 26778 (first part).


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197380 13f79535-47bb-0310-9956-ffa450edef68
pull/30/head
Finn Bock 20 years ago
parent
commit
0d2974463c
23 changed files with 873 additions and 530 deletions
  1. 6
    2
      src/java/org/apache/fop/datatypes/Length.java
  2. 9
    3
      src/java/org/apache/fop/datatypes/LengthBase.java
  3. 99
    0
      src/java/org/apache/fop/datatypes/Numeric.java
  4. 6
    0
      src/java/org/apache/fop/datatypes/PercentBase.java
  5. 3
    2
      src/java/org/apache/fop/fo/expr/AbsFunction.java
  6. 4
    3
      src/java/org/apache/fop/fo/expr/BodyStartFunction.java
  7. 10
    12
      src/java/org/apache/fop/fo/expr/LabelEndFunction.java
  8. 4
    3
      src/java/org/apache/fop/fo/expr/MaxFunction.java
  9. 5
    4
      src/java/org/apache/fop/fo/expr/MinFunction.java
  10. 265
    0
      src/java/org/apache/fop/fo/expr/NumericOp.java
  11. 53
    330
      src/java/org/apache/fop/fo/expr/NumericProperty.java
  12. 1
    1
      src/java/org/apache/fop/fo/expr/PPColWidthFunction.java
  13. 15
    16
      src/java/org/apache/fop/fo/expr/PropertyParser.java
  14. 235
    0
      src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java
  15. 19
    0
      src/java/org/apache/fop/fo/properties/AutoLength.java
  16. 2
    1
      src/java/org/apache/fop/fo/properties/CondLengthProperty.java
  17. 33
    9
      src/java/org/apache/fop/fo/properties/FixedLength.java
  18. 7
    6
      src/java/org/apache/fop/fo/properties/IndentPropertyMaker.java
  19. 13
    72
      src/java/org/apache/fop/fo/properties/LengthProperty.java
  20. 31
    13
      src/java/org/apache/fop/fo/properties/NumberProperty.java
  21. 20
    27
      src/java/org/apache/fop/fo/properties/PercentLength.java
  22. 5
    4
      src/java/org/apache/fop/fo/properties/Property.java
  23. 28
    22
      src/java/org/apache/fop/fo/properties/TableColLength.java

+ 6
- 2
src/java/org/apache/fop/datatypes/Length.java View File

@@ -53,12 +53,16 @@ package org.apache.fop.datatypes;
/**
* A length quantity in XSL
*/
public interface Length {

public interface Length extends Numeric {
/**
* Returns the length in 1/1000ths of a point (millipoints)
* @return the length in millipoints
*/
public int getValue();

/**
* Return true if the length has the "auto" value.
* @return true when length is auto.
*/
public boolean isAuto();
}

+ 9
- 3
src/java/org/apache/fop/datatypes/LengthBase.java View File

@@ -70,6 +70,11 @@ public class LengthBase implements PercentBase {
public static final int CONTAINING_BOX = 3;
/** constant for a containing refarea percent-based length */
public static final int CONTAINING_REFAREA = 4;
/** constant for a containing block percent-based length */
public static final int BLOCK_WIDTH = 5;
/** constant for a containing block percent-based length */
public static final int BLOCK_HEIGHT = 6;

/** array of valid percent-based length types */
public static final int[] PERCENT_BASED_LENGTH_TYPES
= { CUSTOM_BASE, FONTSIZE, INH_FONTSIZE, CONTAINING_BOX,
@@ -143,9 +148,10 @@ public class LengthBase implements PercentBase {
return propertyList.get(Constants.PR_FONT_SIZE).getLength().getValue();
case INH_FONTSIZE:
return propertyList.getInherited(Constants.PR_FONT_SIZE).getLength().getValue();
//case CONTAINING_BOX:
// depends on property?? inline-progression vs block-progression
//return parentFO.getContentWidth();
case BLOCK_WIDTH:
return parentFO.getLayoutDimension(PercentBase.BLOCK_IPD).intValue();
case BLOCK_HEIGHT:
return parentFO.getLayoutDimension(PercentBase.BLOCK_BPD).intValue();
case CONTAINING_REFAREA: // example: start-indent, end-indent
{
//FONode fo;

+ 99
- 0
src/java/org/apache/fop/datatypes/Numeric.java View File

@@ -0,0 +1,99 @@
/*
* $Id$
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by the Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "FOP" and "Apache Software Foundation" must not be used to
* endorse or promote products derived from this software without prior
* written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache", nor may
* "Apache" appear in their name, without prior written permission of the
* Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
* DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ============================================================================
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the Apache Software Foundation and was originally created by
* James Tauber <jtauber@jtauber.com>. For more information on the Apache
* Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.fop.datatypes;

import org.apache.fop.fo.expr.PropertyException;

/**
* An interface for classes that can participate in numeric operations.
* All the numeric operation (+, -, *, ...) are expressed in terms of
* this Numeric interface.
* Numerics has a value (getNumericValue) and a dimension (getDimension).
* Numerics can be either absolute or relative. Relative numerics
* must be resolved against base value before the value can be used.
* <p>
* To support relative numerics internally in the expresion parser and
* during evaulation one additional methods exists: isAbsolute() which
* return true for absolute numerics and false for relative numerics.
*/
public interface Numeric {
/**
* Return the value of this Numeric
* @return the computed value.
* @throws PropertyException
*/
double getNumericValue() throws PropertyException;
/**
* Return the dimension of this numeric. Plain numbers has a dimension of
* 0 and length has a dimension of 1. Other dimension can occur as a result
* of multiplications and divisions.
* @return the dimension.
*/
int getDimension();

/**
* Return true if the numeric is an absolute value. Relative values are
* percentages and table-column-units. All other numerics are absolute.
* @return true when the numeric is absolute.
*/
boolean isAbsolute();
/**
* Return the resolved value. This method will becalled during evaluation
* of the expression tree and relative numerics can then return a
* resolved absolute Numeric. Absolute numerics can just return themself.
*
* @return A resolved value.
* @throws PropertyException
*/
//Numeric getResolved() throws PropertyException;
}

+ 6
- 0
src/java/org/apache/fop/datatypes/PercentBase.java View File

@@ -55,6 +55,12 @@ package org.apache.fop.datatypes;
* computations
*/
public interface PercentBase {
static Integer TABLE_UNITS = new Integer(1);
static Integer BLOCK_IPD = new Integer(2);
static Integer BLOCK_BPD = new Integer(3);
static Integer REFERENCE_AREA_IPD = new Integer(4);
static Integer REFERENCE_AREA_BPD = new Integer(5);
int getDimension();
double getBaseValue();


+ 3
- 2
src/java/org/apache/fop/fo/expr/AbsFunction.java View File

@@ -50,6 +50,7 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.properties.Property;

/**
@@ -73,12 +74,12 @@ public class AbsFunction extends FunctionBase {
*/
public Property eval(Property[] args,
PropertyInfo propInfo) throws PropertyException {
NumericProperty num = args[0].getNumeric();
Numeric num = args[0].getNumeric();
if (num == null) {
throw new PropertyException("Non numeric operand to abs function");
}
// TODO: What if it has relative components (percent, table-col units)?
return num.abs();
return (Property) NumericOp.abs(num);
}

}

+ 4
- 3
src/java/org/apache/fop/fo/expr/BodyStartFunction.java View File

@@ -50,6 +50,7 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.ListItem;
@@ -77,7 +78,7 @@ public class BodyStartFunction extends FunctionBase {
*/
public Property eval(Property[] args,
PropertyInfo pInfo) throws PropertyException {
NumericProperty distance =
Numeric distance =
pInfo.getPropertyList().get(Constants.PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getNumeric();

FONode item = pInfo.getFO();
@@ -88,10 +89,10 @@ public class BodyStartFunction extends FunctionBase {
throw new PropertyException("body-start() called from outside an fo:list-item");
}

NumericProperty startIndent =
Numeric startIndent =
((ListItem)item).propertyList.get(Constants.PR_START_INDENT).getNumeric();

return distance.add(startIndent);
return (Property) NumericOp.addition(distance, startIndent);
}

}

+ 10
- 12
src/java/org/apache/fop/fo/expr/LabelEndFunction.java View File

@@ -50,12 +50,12 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.LengthBase;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.properties.LengthProperty;
import org.apache.fop.fo.properties.LinearCombinationLength;
import org.apache.fop.fo.properties.PercentLength;
import org.apache.fop.fo.properties.Property;

@@ -83,9 +83,9 @@ public class LabelEndFunction extends FunctionBase {
public Property eval(Property[] args,
PropertyInfo pInfo) throws PropertyException {

LengthProperty distance =
Length distance =
pInfo.getPropertyList().get(Constants.PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getLength();
LengthProperty separation =
Length separation =
pInfo.getPropertyList().getNearestSpecified(Constants.PR_PROVISIONAL_LABEL_SEPARATION).getLength();

FONode item = pInfo.getFO();
@@ -95,21 +95,19 @@ public class LabelEndFunction extends FunctionBase {
if (item == null) {
throw new PropertyException("label-end() called from outside an fo:list-item");
}
LengthProperty startIndent = ((ListItem)item).propertyList.get(Constants.PR_START_INDENT).getLength();

LinearCombinationLength labelEnd = new LinearCombinationLength();
Length startIndent = ((ListItem)item).propertyList.get(Constants.PR_START_INDENT).getLength();

// Should be CONTAINING_REFAREA but that doesn't work
LengthBase base = new LengthBase((ListItem)item, pInfo.getPropertyList(),
LengthBase.CONTAINING_BOX);
PercentLength refWidth = new PercentLength(1.0, base);

labelEnd.addTerm(1.0, refWidth);
labelEnd.addTerm(-1.0, distance);
labelEnd.addTerm(-1.0, startIndent);
labelEnd.addTerm(1.0, separation);
Numeric labelEnd = refWidth;
labelEnd = NumericOp.addition(labelEnd, NumericOp.negate(distance));
labelEnd = NumericOp.addition(labelEnd, NumericOp.negate(startIndent));
labelEnd = NumericOp.addition(labelEnd, separation);

return labelEnd;
return (Property) labelEnd;
}

}

+ 4
- 3
src/java/org/apache/fop/fo/expr/MaxFunction.java View File

@@ -50,6 +50,7 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.properties.Property;

/**
@@ -74,12 +75,12 @@ public class MaxFunction extends FunctionBase {
*/
public Property eval(Property[] args,
PropertyInfo pInfo) throws PropertyException {
NumericProperty n1 = args[0].getNumeric();
NumericProperty n2 = args[1].getNumeric();
Numeric n1 = args[0].getNumeric();
Numeric n2 = args[1].getNumeric();
if (n1 == null || n2 == null) {
throw new PropertyException("Non numeric operands to max function");
}
return n1.max(n2);
return (Property) NumericOp.max(n1, n2);
}

}

+ 5
- 4
src/java/org/apache/fop/fo/expr/MinFunction.java View File

@@ -50,6 +50,7 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.properties.Property;

/**
@@ -74,13 +75,13 @@ public class MinFunction extends FunctionBase {
*/
public Property eval(Property[] args,
PropertyInfo pInfo) throws PropertyException {
NumericProperty n1 = args[0].getNumeric();
NumericProperty n2 = args[1].getNumeric();
Numeric n1 = args[0].getNumeric();
Numeric n2 = args[1].getNumeric();
if (n1 == null || n2 == null) {
throw new PropertyException("Non numeric operands to min function");
}
return n1.min(n2);
}
return (Property) NumericOp.min(n1, n2);
}

}


+ 265
- 0
src/java/org/apache/fop/fo/expr/NumericOp.java View File

@@ -0,0 +1,265 @@
/*
* $Id$
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by the Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "FOP" and "Apache Software Foundation" must not be used to
* endorse or promote products derived from this software without prior
* written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache", nor may
* "Apache" appear in their name, without prior written permission of the
* Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
* DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ============================================================================
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the Apache Software Foundation and was originally created by
* James Tauber <jtauber@jtauber.com>. For more information on the Apache
* Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;

/**
* This class contains static methods to evaluate operations on Numeric
* operands. If the operands are absolute numerics the result is computed
* rigth away and a new absolute numeric is return. If one of the operands are
* relative a n operation node is created with the operation and the operands.
* The evaluation of the operation can then occur when getNumericValue() is
* called.
*/
public class NumericOp {
/**
* Add the two operands and return a new Numeric representing the result.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public static Numeric addition(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return addition2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.ADDITION, op1, op2);
}
}
public static Numeric addition2(Numeric op1, Numeric op2) throws PropertyException {
if (op1.getDimension() != op2.getDimension()) {
throw new PropertyException("Can't subtract Numerics of different dimensions");
}
return numeric(op1.getNumericValue() + op2.getNumericValue(), op1.getDimension());
}
/**
* Add the second operand from the first and return a new Numeric
* representing the result.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public static Numeric subtraction(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return subtraction2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.SUBTRACTION, op1, op2);
}
}

public static Numeric subtraction2(Numeric op1, Numeric op2) throws PropertyException {
if (op1.getDimension() != op2.getDimension()) {
throw new PropertyException("Can't subtract Numerics of different dimensions");
}
return numeric(op1.getNumericValue() - op2.getNumericValue(), op1.getDimension());
}
/**
* Multiply the two operands and return a new Numeric representing the
* result.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public static Numeric multiply(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return multiply2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.MULTIPLY, op1, op2);
}
}

public static Numeric multiply2(Numeric op1, Numeric op2) throws PropertyException {
return numeric(op1.getNumericValue() * op2.getNumericValue(),
op1.getDimension() + op2.getDimension());
}
/**
* Divide the second operand into the first and return a new
* Numeric representing the
* result.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public static Numeric divide(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return divide2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.DIVIDE, op1, op2);
}
}
public static Numeric divide2(Numeric op1, Numeric op2) throws PropertyException {
return numeric(op1.getNumericValue() / op2.getNumericValue(),
op1.getDimension() - op2.getDimension());
}
/**
* Return the remainder of a division of the two operand Numeric.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A new Numeric object representing the absolute value.
*/
public static Numeric modulo(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return modulo2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.MODULO, op1, op2);
}
}
public static Numeric modulo2(Numeric op1, Numeric op2) throws PropertyException {
return numeric(op1.getNumericValue() % op2.getNumericValue(), op1.getDimension());
}

/**
* Return the absolute value of the operand Numeric.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A new Numeric object representing the absolute value.
*/
public static Numeric abs(Numeric op) throws PropertyException {
if (op.isAbsolute()) {
return abs2(op);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.ABS, op);
}
}

public static Numeric abs2(Numeric op) throws PropertyException {
return numeric(Math.abs(op.getNumericValue()), op.getDimension());
}
/**
* Return the absolute value of the operand Numeric.
* @param op1 The first operand.
* @param op2 The second operand.
* @return A new Numeric object representing the absolute value.
*/
public static Numeric negate(Numeric op) throws PropertyException {
if (op.isAbsolute()) {
return negate2(op);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.NEGATE, op);
}
}

public static Numeric negate2(Numeric op) throws PropertyException {
return numeric(- op.getNumericValue(), op.getDimension());
}
/**
* Return the largest of the two operands.
* @param op1 The first operand.
* @param op2 The second operand.
* @return a Numeric which is the maximum of the two operands.
* @throws PropertyException If the dimensions or value types of the
* object and the operand are different.
*/
public static Numeric max(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return max2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.MAX, op1, op2);
}
}

public static Numeric max2(Numeric op1, Numeric op2) throws PropertyException {
if (op1.getDimension() != op2.getDimension()) {
throw new PropertyException("Arguments to max() must have same dimensions");
}
return op1.getNumericValue() > op2.getNumericValue() ? op1 : op2;
}
/**
* Return the smallest of the two operands.
* @param op1 The first operand.
* @param op2 The second operand.
* @return a Numeric which is the minimum of the two operands.
* @throws PropertyException If the dimensions or value types of the
* object and the operand are different.
*/
public static Numeric min(Numeric op1, Numeric op2) throws PropertyException {
if (op1.isAbsolute() && op2.isAbsolute()) {
return min2(op1, op2);
} else {
return new RelativeNumericProperty(RelativeNumericProperty.MIN, op1, op2);
}
}

public static Numeric min2(Numeric op1, Numeric op2) throws PropertyException {
if (op1.getDimension() != op2.getDimension()) {
throw new PropertyException("Arguments to min() must have same dimensions");
}
return op1.getNumericValue() <= op2.getNumericValue() ? op1 : op2;
}
/**
* Create a new absolute numeric with the specified value and dimension.
* @param value
* @param dimension
* @return a new absolute numeric.
*/
private static Numeric numeric(double value, int dimension) {
return new NumericProperty(value, dimension);
}
}

+ 53
- 330
src/java/org/apache/fop/fo/expr/NumericProperty.java View File

@@ -50,393 +50,116 @@
*/
package org.apache.fop.fo.expr;

import java.util.Vector;

import org.apache.fop.datatypes.PercentBase;

import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.properties.ColorTypeProperty;
import org.apache.fop.fo.properties.FixedLength;
import org.apache.fop.fo.properties.LengthProperty;
import org.apache.fop.fo.properties.MixedLength;
import org.apache.fop.fo.properties.PercentLength;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.TableColLength;

public class NumericProperty extends Property {
// Bit fields

/** constant for a length of absolute units (or number) */
public static final int ABS_LENGTH = 1;
/** constant for a percentage */
public static final int PC_LENGTH = 2;
/** constant for table units */
public static final int TCOL_LENGTH = 4;

private int valType;
private double absValue;
private double pcValue;
private PercentBase pcBase = null; // base value for PC_LENGTH component
private double tcolValue;
/**
* A numeric property which hold the final absolute result of an expression
* calculations.
*/
public class NumericProperty extends Property implements Numeric, Length {
private double value;
private int dim;


/**
* Construct a Numeric object by specifying one or more components,
* including absolute length, percent length, table units.
* @param valType A combination of bits representing the value types.
* @param absValue The value of a Number or resolved Length value if
* the ABS_LENGTH flag is set.
* @param pcValue The decimal percent value if the PC_LENGTH flag is set
* @param tcolValue The decimal table unit value if the TCOL_LENGTH flag
* is set.
* @param value The value of the numeric.
* @param dim The dimension of the value. 0 for a Number, 1 for a Length
* (any type), >1, <0 if Lengths have been multiplied or divided.
* @param pcBase The PercentBase object used to calculate an actual value for
* a PC_LENGTH.
*/
protected NumericProperty(int valType, double absValue, double pcValue,
double tcolValue, int dim, PercentBase pcBase) {
this.valType = valType;
this.absValue = absValue;
this.pcValue = pcValue;
this.tcolValue = tcolValue;
protected NumericProperty(double value, int dim) {
this.value = value;
this.dim = dim;
this.pcBase = pcBase;
}

/**
* Construct a Numeric object of dimension 0 from a double.
* @param valType A combination of bits representing the value types.
* @param absValue The value of a Number or resolved Length value.
*/

/**
* *
* protected Numeric(int valType, double absValue) {
* this.valType = valType;
* this.absValue = absValue;
* }
*/

/**
* Construct a Numeric object from a Number.
* @param num The number.
*/
public NumericProperty(Number num) {
this(ABS_LENGTH, num.doubleValue(), 0.0, 0.0, 0, null);
}

/**
* Construct a Numeric object from a Length.
* @param l The Length.
*/
public NumericProperty(FixedLength l) {
this(ABS_LENGTH, (double)l.getValue(), 0.0, 0.0, 1, null);
}

/**
* Construct a Numeric object from a PercentLength.
* @param pclen The PercentLength.
*/
public NumericProperty(PercentLength pclen) {
this(PC_LENGTH, 0.0, pclen.value(), 0.0, 1, pclen.getBaseLength());
}

/**
* Construct a Numeric object from a TableColLength.
* @param tclen The TableColLength.
*/
public NumericProperty(TableColLength tclen) {
this(TCOL_LENGTH, 0.0, 0.0, tclen.getTableUnits(), 1, null);
}


/**
* @return the current value as a Length if possible. This constructs
* a new Length or Length subclass based on the current value type
* of the Numeric.
* If the stored value has a unit dimension other than 1, null
* is returned.
* Return the dimension.
* @see Numeric#getDimension()
*/
public LengthProperty asLength() {
if (dim == 1) {
Vector len = new Vector(3);
if ((valType & ABS_LENGTH) != 0) {
len.add(new FixedLength((int)absValue));
}
if ((valType & PC_LENGTH) != 0) {
len.add(new PercentLength(pcValue, pcBase));
}
if ((valType & TCOL_LENGTH) != 0) {
len.add(new TableColLength(tcolValue));
}
if (len.size() == 1) {
return (LengthProperty)len.elementAt(0);
} else {
return new MixedLength(len);
}
} else {
// or throw exception???
// can't make Length if dimension != 1
return null;
}
public int getDimension() {
return dim;
}

/**
* @return the current value as a Number if possible.
* Calls asDouble().
* Return the value.
* @see Numeric#getNumericValue()
*/
public Number asNumber() {
return asDouble();
public double getNumericValue() {
return value;
}

/**
* @return the current value as a Double
* Return true of the numeric is absolute.
* @see Numeric#isAbsolute()
*/
public Double asDouble() {
if (dim == 0 && valType == ABS_LENGTH) {
return new Double(absValue);
} else {
// or throw exception???
// can't make Number if dimension != 0
return null;
}
public boolean isAbsolute() {
return true;
}

/**
* Return the current value as a Integer if possible.
* If the unit dimension is 0 and the value type is ABSOLUTE, an Integer
* is returned. Otherwise null is returned. Note: the current value is
* truncated if necessary to make an integer value.
* Cast this as a Numeric.
*/

/**
* public Integer asInteger() {
* if (dim == 0 && valType==ABS_LENGTH) {
* return new Integer((int)absValue);
* }
* else {
* // or throw exception???
* // can't make Number if dimension != 0
* return null;
* }
* }
*/

/**
* Return a boolean value indiciating whether the currently stored
* value consists of different "types" of values (absolute, percent,
* and/or table-unit.)
*/
private boolean isMixedType() {
int ntype = 0;
for (int t = valType; t != 0; t = t >> 1) {
if ((t & 1) != 0) {
++ntype;
}
}
return ntype > 1;
}

/**
* Subtract the operand from the current value and return a new Numeric
* representing the result.
* @param op The value to subtract.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public NumericProperty subtract(NumericProperty op) throws PropertyException {
// Check of same dimension
// Add together absolute and table units
// What about percentages??? Treat as colUnits if they can't be
// in same property!
if (dim == op.dim) {
PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase
: op.pcBase;
// Subtract each type of value
return new NumericProperty(valType | op.valType, absValue - op.absValue,
pcValue - op.pcValue,
tcolValue - op.tcolValue, dim, npcBase);
} else {
throw new PropertyException("Can't add Numerics of different dimensions");
}
}

/**
* Add the operand from the current value and return a new Numeric
* representing the result.
* @param op The value to add.
* @return A Numeric representing the result.
* @throws PropertyException If the dimension of the operand is different
* from the dimension of this Numeric.
*/
public NumericProperty add(NumericProperty op) throws PropertyException {
// Check of same dimension
// Add together absolute and table units
// What about percentages??? Treat as colUnits if they can't be
// in same property!
if (dim == op.dim) {
PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase
: op.pcBase;
// Add each type of value
return new NumericProperty(valType | op.valType, absValue + op.absValue,
pcValue + op.pcValue,
tcolValue + op.tcolValue, dim, npcBase);
} else {
throw new PropertyException("Can't add Numerics of different dimensions");
}
public Numeric getNumeric() {
return this;
}

/**
* Multiply the the current value by the operand and return a new Numeric
* representing the result.
* @param op The multiplier.
* @return A Numeric representing the result.
* @throws PropertyException If both Numerics have "mixed" type.
* Cast this as a number.
*/
public NumericProperty multiply(NumericProperty op) throws PropertyException {
// Multiply together absolute units and add dimensions (exponents)
// What about percentages??? Treat as colUnits if they can't be
// in same property!
if (dim == 0) {
// This is a dimensionless quantity, ie. a "Number"
return new NumericProperty(op.valType, absValue * op.absValue,
absValue * op.pcValue,
absValue * op.tcolValue, op.dim, op.pcBase);
} else if (op.dim == 0) {
double opval = op.absValue;
return new NumericProperty(valType, opval * absValue, opval * pcValue,
opval * tcolValue, dim, pcBase);
} else if (valType == op.valType && !isMixedType()) {
// Check same relbase and pcbase ???
PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase
: op.pcBase;
return new NumericProperty(valType, absValue * op.absValue,
pcValue * op.pcValue,
tcolValue * op.tcolValue, dim + op.dim,
npcBase);
} else {
throw new PropertyException("Can't multiply mixed Numerics");
}
public Number getNumber() {
return new Double(value);
}

/**
* Divide the the current value by the operand and return a new Numeric
* representing the result.
* @param op The divisor.
* @return A Numeric representing the result.
* @throws PropertyException If both Numerics have "mixed" type.
* Return the value of this numeric as a length in millipoints.
*/
public NumericProperty divide(NumericProperty op) throws PropertyException {
// Multiply together absolute units and add dimensions (exponents)
// What about percentages??? Treat as colUnits if they can't be
// in same property!
if (dim == 0) {
// This is a dimensionless quantity, ie. a "Number"
return new NumericProperty(op.valType, absValue / op.absValue,
absValue / op.pcValue,
absValue / op.tcolValue, -op.dim, op.pcBase);
} else if (op.dim == 0) {
double opval = op.absValue;
return new NumericProperty(valType, absValue / opval, pcValue / opval,
tcolValue / opval, dim, pcBase);
} else if (valType == op.valType && !isMixedType()) {
PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase
: op.pcBase;
return new NumericProperty(valType,
(valType == ABS_LENGTH ? absValue / op.absValue : 0.0),
(valType == PC_LENGTH ? pcValue / op.pcValue : 0.0),
(valType == TCOL_LENGTH ? tcolValue / op.tcolValue : 0.0),
dim - op.dim, npcBase);
} else {
throw new PropertyException("Can't divide mixed Numerics.");
}
public int getValue() {
return (int) value;
}

/**
* Return the absolute value of this Numeric.
* @return A new Numeric object representing the absolute value.
* Return false since a numeric can not have the enum value of 'auto'.
*/
public NumericProperty abs() {
return new NumericProperty(valType, Math.abs(absValue), Math.abs(pcValue),
Math.abs(tcolValue), dim, pcBase);
public boolean isAuto() {
return false;
}

/**
* @param op the operand to which the current value should be compared
* @return a Numeric which is the maximum of the current value and the
* operand.
* @throws PropertyException If the dimensions or value types of the
* object and the operand are different.
* Cast this as a length. That is only possible when the dimension is
* one.
*/
public NumericProperty max(NumericProperty op) throws PropertyException {
double rslt = 0.0;
// Only compare if have same dimension and value type!
if (dim == op.dim && valType == op.valType && !isMixedType()) {
if (valType == ABS_LENGTH) {
rslt = absValue - op.absValue;
} else if (valType == PC_LENGTH) {
rslt = pcValue - op.pcValue;
} else if (valType == TCOL_LENGTH) {
rslt = tcolValue - op.tcolValue;
}
if (rslt > 0.0) {
return this;
} else {
return op;
}
public Length getLength() {
if (dim == 1) {
return this;
}
throw new PropertyException("Arguments to max() must have same dimension and value type.");
System.err.print("Can't create length with dimension " + dim);
return null;
}

/**
* @param op the operand to which the current value should be compared
* @return a Numeric which is the minimum of the current value and the
* operand.
* @throws PropertyException If the dimensions or value types of the
* object and the operand are different.
* Cast this as a ColorTypeProperty.
*/
public NumericProperty min(NumericProperty op) throws PropertyException {
double rslt = 0.0;
// Only compare if have same dimension and value type!
if (dim == op.dim && valType == op.valType && !isMixedType()) {
if (valType == ABS_LENGTH) {
rslt = absValue - op.absValue;
} else if (valType == PC_LENGTH) {
rslt = pcValue - op.pcValue;
} else if (valType == TCOL_LENGTH) {
rslt = tcolValue - op.tcolValue;
}
if (rslt > 0.0) {
return op;
} else {
return this;
}
}
throw new PropertyException("Arguments to min() must have same dimension and value type.");
}

public NumericProperty getNumeric() {
return this;
}

public Number getNumber() {
return asNumber();
}

public LengthProperty getLength() {
return asLength();
}

public ColorTypeProperty getColorType() {
// try converting to numeric number and then to color
return null;
}

/**
* Cast this as an Object.
*/
public Object getObject() {
return this;
}

/**
* Return a string representation of this Numeric. It is only useable for
* debugging.
*/
public String toString() {
return value + "^" + dim;
}
}

+ 1
- 1
src/java/org/apache/fop/fo/expr/PPColWidthFunction.java View File

@@ -89,7 +89,7 @@ public class PPColWidthFunction extends FunctionBase {
+ "may only be used on table-column FO");
}
// Check if table-layout is "fixed"...
return new TableColLength(d.doubleValue());
return new TableColLength(d.doubleValue(), pInfo.getFO());
}

}

+ 15
- 16
src/java/org/apache/fop/fo/expr/PropertyParser.java View File

@@ -50,6 +50,7 @@
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.datatypes.PercentBase;
import org.apache.fop.fo.properties.ColorTypeProperty;
import org.apache.fop.fo.properties.FixedLength;
@@ -71,7 +72,6 @@ public class PropertyParser extends PropertyTokenizer {
private PropertyInfo propInfo; // Maker and propertyList related info

private static final String RELUNIT = "em";
private static final NumericProperty NEGATIVE_ONE = new NumericProperty(new Double(-1.0));
private static final HashMap FUNCTION_TABLE = new HashMap();

static {
@@ -291,7 +291,6 @@ public class PropertyParser extends PropertyTokenizer {
*/
double pcval = new Double(currentTokenValue.substring(0,
currentTokenValue.length() - 1)).doubleValue() / 100.0;
// LengthBase lbase = this.propInfo.getPercentLengthBase();
PercentBase pcBase = this.propInfo.getPercentBase();
if (pcBase != null) {
if (pcBase.getDimension() == 0) {
@@ -401,12 +400,12 @@ public class PropertyParser extends PropertyTokenizer {
* the sum of the two operands.
* @throws PropertyException If either operand is null.
*/
private Property evalAddition(NumericProperty op1,
NumericProperty op2) throws PropertyException {
private Property evalAddition(Numeric op1,
Numeric op2) throws PropertyException {
if (op1 == null || op2 == null) {
throw new PropertyException("Non numeric operand in addition");
}
return op1.add(op2);
return (Property) NumericOp.addition(op1, op2);
}

/**
@@ -418,12 +417,12 @@ public class PropertyParser extends PropertyTokenizer {
* the difference of the two operands.
* @throws PropertyException If either operand is null.
*/
private Property evalSubtraction(NumericProperty op1,
NumericProperty op2) throws PropertyException {
private Property evalSubtraction(Numeric op1,
Numeric op2) throws PropertyException {
if (op1 == null || op2 == null) {
throw new PropertyException("Non numeric operand in subtraction");
}
return op1.subtract(op2);
return (Property) NumericOp.subtraction(op1, op2);
}

/**
@@ -434,11 +433,11 @@ public class PropertyParser extends PropertyTokenizer {
* the negative of the operand (multiplication by *1).
* @throws PropertyException If the operand is null.
*/
private Property evalNegate(NumericProperty op) throws PropertyException {
private Property evalNegate(Numeric op) throws PropertyException {
if (op == null) {
throw new PropertyException("Non numeric operand to unary minus");
}
return op.multiply(NEGATIVE_ONE);
return (Property) NumericOp.negate(op);
}

/**
@@ -450,12 +449,12 @@ public class PropertyParser extends PropertyTokenizer {
* the product of the two operands.
* @throws PropertyException If either operand is null.
*/
private Property evalMultiply(NumericProperty op1,
NumericProperty op2) throws PropertyException {
private Property evalMultiply(Numeric op1,
Numeric op2) throws PropertyException {
if (op1 == null || op2 == null) {
throw new PropertyException("Non numeric operand in multiplication");
}
return op1.multiply(op2);
return (Property) NumericOp.multiply(op1, op2);
}


@@ -468,12 +467,12 @@ public class PropertyParser extends PropertyTokenizer {
* op1 divided by op2.
* @throws PropertyException If either operand is null.
*/
private Property evalDivide(NumericProperty op1,
NumericProperty op2) throws PropertyException {
private Property evalDivide(Numeric op1,
Numeric op2) throws PropertyException {
if (op1 == null || op2 == null) {
throw new PropertyException("Non numeric operand in division");
}
return op1.divide(op2);
return (Property) NumericOp.divide(op1, op2);
}

/**

+ 235
- 0
src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java View File

@@ -0,0 +1,235 @@
/*
* $Id$
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by the Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "FOP" and "Apache Software Foundation" must not be used to
* endorse or promote products derived from this software without prior
* written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache", nor may
* "Apache" appear in their name, without prior written permission of the
* Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
* DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ============================================================================
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the Apache Software Foundation and was originally created by
* James Tauber <jtauber@jtauber.com>. For more information on the Apache
* Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.fop.fo.expr;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.properties.Property;


/**
* This class represent a node in a property expression tree.
* It is created when an operation involve relative expression and is used
* to delay evaluation of the operation until the time where getNumericValue()
* or getValue() is called.
*/
public class RelativeNumericProperty extends Property implements Numeric, Length {
public static final int ADDITION = 1;
public static final int SUBTRACTION = 2;
public static final int MULTIPLY = 3;
public static final int DIVIDE = 4;
public static final int MODULO = 5;
public static final int NEGATE = 6;
public static final int ABS = 7;
public static final int MAX = 8;
public static final int MIN = 9;
// Used in the toString() method, indexed by operation id.
private static String operations = " +-*/%";
/**
* The operation identifier.
*/
private int operation;
/**
* The first (or only) operand.
*/
private Numeric op1;
/**
* The second operand.
*/
private Numeric op2;
/**
* The dimension of the result.
*/
private int dimension;
/**
* Constructor for a two argument operation.
* @param operation the operation opcode: ADDITION, SUBTRACTION, ...
* @param op1 the first operand.
* @param op2 the second operand
*/
public RelativeNumericProperty(int operation, Numeric op1, Numeric op2) {
this.operation = operation;
this.op1 = op1;
this.op2 = op2;
// Calculate the dimension. We can do now.
switch (operation) {
case MULTIPLY:
dimension = op1.getDimension() + op2.getDimension();
break;
case DIVIDE:
dimension = op1.getDimension() - op2.getDimension();
break;
default:
dimension = op1.getDimension();
}
}

/**
* Constructor for a one argument operation.
* @param operation the operation opcode: NEGATE, ABS
* @param op the operand.
*/
public RelativeNumericProperty(int operation, Numeric op) {
this.operation = operation;
this.op1 = op;
this.dimension = op.getDimension();
}

/**
* Return a resolved (calculated) Numeric with the value of the expression.
* @throws PropertyException when an exception occur during evaluation.
*/
private Numeric getResolved() throws PropertyException {
Numeric n;
switch (operation) {
case ADDITION:
return NumericOp.addition2(op1, op2);
case SUBTRACTION:
return NumericOp.subtraction2(op1, op2);
case MULTIPLY:
return NumericOp.multiply2(op1, op2);
case DIVIDE:
return NumericOp.divide2(op1, op2);
case MODULO:
return NumericOp.modulo2(op1, op2);
case NEGATE:
return NumericOp.negate2(op1);
case ABS:
return NumericOp.abs2(op1);
case MAX:
return NumericOp.max2(op1, op2);
case MIN:
return NumericOp.min2(op1, op2);
default:
throw new PropertyException("Unknown expr operation " + operation);
}
}

/**
* Return the resolved (calculated) value of the expression.
* @see Numeric#getNumericValue()
*/
public double getNumericValue() throws PropertyException {
return getResolved().getNumericValue();
}

/**
* Return the dimension of the expression
*/
public int getDimension() {
return dimension;
}

/**
* Return false since an expression is only created when there is relative
* numerics involved.
*/
public boolean isAbsolute() {
return false;
}

/**
* Cast this numeric as a Length.
*/
public Length getLength() {
if (dimension == 1) {
return this;
}
System.err.print("Can't create length with dimension " + dimension);
return null;
}

public Numeric getNumeric() {
return this;
}

/**
* Return a resolved length.
*/
public int getValue() {
try {
return (int) getNumericValue();
} catch (PropertyException exc) {
exc.printStackTrace();
}
return 0;
}

/**
* Return false, since a numeric is never the "auto" enum.
*/
public boolean isAuto() {
return false;
}

/**
* Return a string represention of the expression. Only used for debugging.
*/
public String toString() {
switch (operation) {
case ADDITION: case SUBTRACTION:
case DIVIDE: case MULTIPLY: case MODULO:
return "(" + op1 + " " + operations.charAt(operation) + op2 + ")";
case NEGATE:
return "-" + op1;
case MAX:
return "max(" + op1 + ", " + op2 + ")";
case MIN:
return "min(" + op1 + ", " + op2 + ")";
case ABS:
return "abs(" + op1 + ")";
}
return "unknown operation " + operation;
}
}

+ 19
- 0
src/java/org/apache/fop/fo/properties/AutoLength.java View File

@@ -68,6 +68,25 @@ public class AutoLength extends LengthProperty {
// protected void computeValue() {
// }

public boolean isAbsolute() {
return false;
}
/**
* Returns the length in 1/1000ths of a point (millipoints)
* @return the length in millipoints
*/
public int getValue() {
return 0;
}

/**
* Returns the value as numeric.
* @return the length in millipoints
*/
public double getNumericValue() {
return 0;
}

/**
* @see org.apache.fop.fo.properties.Property#getString()
*/

+ 2
- 1
src/java/org/apache/fop/fo/properties/CondLengthProperty.java View File

@@ -52,6 +52,7 @@ package org.apache.fop.fo.properties;

import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.CompoundDatatype;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
@@ -170,7 +171,7 @@ public class CondLengthProperty extends Property implements CompoundDatatype {
* TODO: Should we allow this?
* @return this.condLength cast as a Length
*/
public LengthProperty getLength() {
public Length getLength() {
return length.getLength();
}


+ 33
- 9
src/java/org/apache/fop/fo/properties/FixedLength.java View File

@@ -50,12 +50,11 @@
*/
package org.apache.fop.fo.properties;

import org.apache.fop.fo.expr.NumericProperty;

/**
* a length quantity in XSL
* An absolute length quantity in XSL
*/
public class FixedLength extends LengthProperty {
private int millipoints;

/**
* Set the length given
@@ -63,7 +62,7 @@ public class FixedLength extends LengthProperty {
* @param iCurFontSize the current font size in base units.
*/
public FixedLength(double numRelUnits, int iCurFontSize) {
setComputedValue((int)(numRelUnits * (double)iCurFontSize));
millipoints = (int) (numRelUnits * (double)iCurFontSize);
}

/**
@@ -79,7 +78,7 @@ public class FixedLength extends LengthProperty {
* @param baseUnits the length as a number of base units (millipoints)
*/
public FixedLength(int baseUnits) {
setComputedValue(baseUnits);
millipoints = baseUnits;
}

/**
@@ -114,14 +113,39 @@ public class FixedLength extends LengthProperty {
//log.error("unknown length unit '" + unit
// + "'");
}
setComputedValue((int)(dvalue * 1000));
millipoints = (int)(dvalue * 1000);
}

/**
* Returns the length in 1/1000ths of a point (millipoints)
* @return the length in millipoints
*/
public int getValue() {
return millipoints;
}

/**
* Returns the value as numeric.
* @return the length in millipoints
*/
public double getNumericValue() {
return millipoints;
}

/**
* @return Numeric equivalent of this
* Return true since FixedLength are always absolute.
* @see org.apache.fop.datatypes.Numeric#isAbsolute()
*/
public NumericProperty asNumeric() {
return new NumericProperty(this);
public boolean isAbsolute() {
return true;
}

/**
* @see java.lang.Object#toString()
*/
public String toString() {
return millipoints + "mpt";
}

}


+ 7
- 6
src/java/org/apache/fop/fo/properties/IndentPropertyMaker.java View File

@@ -51,9 +51,10 @@
package org.apache.fop.fo.properties;

import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.FOPropertyMapping;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.NumericProperty;
import org.apache.fop.fo.expr.NumericOp;

/**
* This property maker handles the calculations described in 5.3.2 which
@@ -106,17 +107,17 @@ public class IndentPropertyMaker extends CorrespondingPropertyMaker {
}
// Calculate the values as described in 5.3.2.
try {
NumericProperty v = new NumericProperty(new FixedLength(0));
Numeric v = new FixedLength(0);
/*
if (!propertyList.getFObj().generatesInlineAreas()) {
String propName = FOPropertyMapping.getPropertyName(this.propId);
v = v.add(propertyList.getInherited(propName).getNumeric());
}
*/
v = v.add(propertyList.get(propertyList.wmMap(lr_tb, rl_tb, tb_rl)).getNumeric());
v = v.add(getCorresponding(paddingCorresponding, propertyList).getNumeric());
v = v.add(getCorresponding(borderWidthCorresponding, propertyList).getNumeric());
return v.asLength();
v = NumericOp.addition(v, propertyList.get(propertyList.wmMap(lr_tb, rl_tb, tb_rl)).getNumeric());
v = NumericOp.addition(v, getCorresponding(paddingCorresponding, propertyList).getNumeric());
v = NumericOp.addition(v, getCorresponding(borderWidthCorresponding, propertyList).getNumeric());
return (Property) v;
} catch (org.apache.fop.fo.expr.PropertyException propEx) {
String propName = FOPropertyMapping.getPropertyName(baseMaker.getPropId());
throw new FOPException("Error in " + propName

+ 13
- 72
src/java/org/apache/fop/fo/properties/LengthProperty.java View File

@@ -52,19 +52,16 @@ package org.apache.fop.fo.properties;

import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.NumericProperty;

/**
* Superclass for properties wrapping a Length value.
*/
public class LengthProperty extends Property implements Length {
/** Holds the length in millipoints. */
protected int millipoints = 0;
/** Indicates if the value has been computed, or not. */
protected boolean bIsComputed = false;

abstract public class LengthProperty extends Property
implements Length, Numeric
{
/**
* Inner class for making instances of LengthProperty
*/
@@ -121,52 +118,15 @@ public class LengthProperty extends Property implements Length {
if (p instanceof LengthProperty) {
return p;
}
LengthProperty val = p.getLength();
Length val = p.getLength();
if (val != null) {
return val;
return (Property) val;
}
return convertPropertyDatatype(p, propertyList, fo);
}

}


/**
* Returns the length in 1/1000ths of a point (millipoints)
* @return the length in millipoints
*/
public int getValue() {
if (!bIsComputed) {
computeValue();
}
return millipoints;
}

/**
* Computes the value.
*/
protected void computeValue() {
}


/**
* Sets the computed value.
* @param millipoints the length in millipoints
*/
protected void setComputedValue(int millipoints) {
setComputedValue(millipoints, true);
}

/**
* Sets the computed value.
* @param millipoints the length in millipoints
* @param bSetComputed True if the isComputed flag should be set.
*/
protected void setComputedValue(int millipoints, boolean bSetComputed) {
this.millipoints = millipoints;
this.bIsComputed = bSetComputed;
}

/**
* Indicates if the length has the "auto" value.
* @return True if the length is set to "auto"
@@ -175,14 +135,6 @@ public class LengthProperty extends Property implements Length {
return false;
}

/**
* Indicates if the length has been computed.
* @return True if the length has been computed
*/
public boolean isComputed() {
return this.bIsComputed;
}

/**
* Return the number of table units which are included in this
* length specification.
@@ -199,35 +151,24 @@ public class LengthProperty extends Property implements Length {
return 0.0;
}

public void resolveTableUnit(double dTableUnit) {
}

/**
* @return null (cannot be converted to a Numeric ??)
* Return the numeric dimension. Length always a dimension of 1.
*/
public NumericProperty asNumeric() {
return null;
public int getDimension() {
return 1;
}

/**
* @see java.lang.Object#toString()
* @return this.length cast as a Numeric
*/
public String toString() {
String s = millipoints + "mpt";
return s;
}

/**
* @return this.lenght cast as a Numeric
*/
public NumericProperty getNumeric() {
return asNumeric() ;
public Numeric getNumeric() {
return this;
}

/**
* @return this.length
*/
public LengthProperty getLength() {
public Length getLength() {
return this;
}


+ 31
- 13
src/java/org/apache/fop/fo/properties/NumberProperty.java View File

@@ -50,14 +50,14 @@
*/
package org.apache.fop.fo.properties;

import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.NumericProperty;

/**
* Class for handling numeric properties
*/
public class NumberProperty extends Property {
public class NumberProperty extends Property implements Numeric {

/**
* Inner class for making NumberProperty objects
@@ -116,20 +116,38 @@ public class NumberProperty extends Property {
}

/**
* @return this.number cast as a Number
* Plain number always has a dimension of 0.
* @return a dimension of 0.
* @see Numeric#getDimension()
*/
public Number getNumber() {
return this.number;
public int getDimension() {
return 0;
}

/**
* Return the value of this Numeric.
* @return The value as a double.
* @see Numeric#getNumericValue()
*/
public double getNumericValue() {
return number.doubleValue();
}

/**
* public Double getDouble() {
* return new Double(this.number.doubleValue());
* }
* public Integer getInteger() {
* return new Integer(this.number.intValue());
* }
* Return true because all numbers are absolute.
* @return true.
* @see Numeric#isAbsolute()
*/
public boolean isAbsolute() {
return true;
}

/**
* @return this.number cast as a Number
*/
public Number getNumber() {
return this.number;
}

/**
* @return this.number cast as an Object
@@ -142,8 +160,8 @@ public class NumberProperty extends Property {
* Convert NumberProperty to Numeric object
* @return Numeric object corresponding to this
*/
public NumericProperty getNumeric() {
return new NumericProperty(this.number);
public Numeric getNumeric() {
return this;
}

/**

+ 20
- 27
src/java/org/apache/fop/fo/properties/PercentLength.java View File

@@ -51,7 +51,6 @@
package org.apache.fop.fo.properties;

import org.apache.fop.datatypes.PercentBase;
import org.apache.fop.fo.expr.NumericProperty;

/**
* a percent specified length quantity in XSL
@@ -84,42 +83,43 @@ public class PercentLength extends LengthProperty {
}

/**
* Convenience constructor when only the factor is known
* @param factor the percentage factor, expressed as a decimal (e.g. use
* .95 to represent 95%)
* @return the base
*/
public PercentLength(double factor) {
this(factor, null);
public PercentBase getBaseLength() {
return this.lbase;
}

/**
* @param lbase the base to set
*
* @return the factor
* TODO: Should this really exists?
*/
public void setBaseLength(PercentBase lbase) {
this.lbase = lbase;
public double value() {
return factor;
}

/**
* @return the base
* Return false because percent-length are always relative.
* @see org.apache.fop.datatypes.Numeric#isAbsolute()
*/
public PercentBase getBaseLength() {
return this.lbase;
public boolean isAbsolute() {
return false;
}

/**
* Return the computed value in millipoints. This assumes that the
* base length has been resolved to an absolute length value.
* Return the value of this Numeric.
* @see org.apache.fop.datatypes.Numeric#getNumericValue()
*/
protected void computeValue() {
setComputedValue((int)(factor * (double)lbase.getBaseLength()));
public double getNumericValue() {
return factor * lbase.getBaseLength();
}

/**
*
* @return the factor
* Return the length of this PercentLength.
* @see org.apache.fop.datatypes.Length#getValue()
*/
public double value() {
return factor;
public int getValue() {
return (int) (factor * lbase.getBaseLength());
}

/**
@@ -130,11 +130,4 @@ public class PercentLength extends LengthProperty {
return (new Double(factor * 100.0).toString()) + "%";
}

/**
* @return new Numeric object that is equivalent to this
*/
public NumericProperty asNumeric() {
return new NumericProperty(this);
}

}

+ 5
- 4
src/java/org/apache/fop/fo/properties/Property.java View File

@@ -50,10 +50,11 @@
*/
package org.apache.fop.fo.properties;

import org.apache.fop.fo.expr.NumericProperty;

import java.util.Vector;

import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.Numeric;

/**
* Base class for all property objects
* @author unascribed
@@ -91,7 +92,7 @@ public class Property {
* This method expects to be overridden by subclasses
* @return Length property value
*/
public LengthProperty getLength() {
public Length getLength() {
return null;
}

@@ -179,7 +180,7 @@ public class Property {
* This method expects to be overridden by subclasses
* @return Numeric property value
*/
public NumericProperty getNumeric() {
public Numeric getNumeric() {
return null;
}


+ 28
- 22
src/java/org/apache/fop/fo/properties/TableColLength.java View File

@@ -50,7 +50,8 @@
*/
package org.apache.fop.fo.properties;

import org.apache.fop.fo.expr.NumericProperty;
import org.apache.fop.datatypes.PercentBase;
import org.apache.fop.fo.FObj;

/**
* A table-column width specification, possibly including some
@@ -64,18 +65,23 @@ import org.apache.fop.fo.expr.NumericProperty;
* NOTE: this is only supposed to be allowed if table-layout=fixed.
*/
public class TableColLength extends LengthProperty {

/**
* Number of table-column proportional units
*/
private double tcolUnits;

/**
* The column the this column-units are defined on.
*/
private FObj column;

/**
* Construct an object with tcolUnits of proportional measure.
* @param tcolUnits number of table-column proportional units
*/
public TableColLength(double tcolUnits) {
public TableColLength(double tcolUnits, FObj column) {
this.tcolUnits = tcolUnits;
this.column = column;
}

/**
@@ -87,20 +93,28 @@ public class TableColLength extends LengthProperty {
}

/**
* Calculate the number of millipoints and set it.
* @param mpointsPerUnit density of millipoints per unit
* Return false because table-col-units are a relative numeric.
* @see org.apache.fop.datatypes.Numeric#isAbsolute()
*/
public void resolveTableUnit(double mpointsPerUnit) {
setComputedValue((int)(tcolUnits * mpointsPerUnit));
public boolean isAbsolute() {
return false;
}

//If the table-unit can be resolved, set the computed value
/*protected void computeValue() {
if (tblUnitBase.canResolveUnit()) {
rslt += (int)(tcolUnits * (double)tblUnitBase.getUnitValue());
setComputedValue(rslt);
}
}*/
/**
* Return the value as a numeric value.
* @see org.apache.fop.datatypes.Numeric#getNumericValue()
*/
public double getNumericValue() {
return tcolUnits * column.getLayoutDimension(PercentBase.TABLE_UNITS).floatValue();
}

/**
* Return the value as a length.
* @see org.apache.fop.datatypes.Length#getValue()
*/
public int getValue() {
return (int) (tcolUnits * column.getLayoutDimension(PercentBase.TABLE_UNITS).floatValue());
}

/**
* Convert this to a String
@@ -110,12 +124,4 @@ public class TableColLength extends LengthProperty {
return (Double.toString(tcolUnits) + " table-column-units");
}

/**
* Converts this to a new Numeric object
* @return the Numeric object
*/
public NumericProperty asNumeric() {
return new NumericProperty(this);
}
}


Loading…
Cancel
Save