Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

RelativeNumericProperty.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * $Id$
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.fo.expr;
  52. import org.apache.fop.datatypes.Numeric;
  53. import org.apache.fop.datatypes.Length;
  54. import org.apache.fop.fo.properties.Property;
  55. /**
  56. * This class represent a node in a property expression tree.
  57. * It is created when an operation involve relative expression and is used
  58. * to delay evaluation of the operation until the time where getNumericValue()
  59. * or getValue() is called.
  60. */
  61. public class RelativeNumericProperty extends Property implements Numeric, Length {
  62. public static final int ADDITION = 1;
  63. public static final int SUBTRACTION = 2;
  64. public static final int MULTIPLY = 3;
  65. public static final int DIVIDE = 4;
  66. public static final int MODULO = 5;
  67. public static final int NEGATE = 6;
  68. public static final int ABS = 7;
  69. public static final int MAX = 8;
  70. public static final int MIN = 9;
  71. // Used in the toString() method, indexed by operation id.
  72. private static String operations = " +-*/%";
  73. /**
  74. * The operation identifier.
  75. */
  76. private int operation;
  77. /**
  78. * The first (or only) operand.
  79. */
  80. private Numeric op1;
  81. /**
  82. * The second operand.
  83. */
  84. private Numeric op2;
  85. /**
  86. * The dimension of the result.
  87. */
  88. private int dimension;
  89. /**
  90. * Constructor for a two argument operation.
  91. * @param operation the operation opcode: ADDITION, SUBTRACTION, ...
  92. * @param op1 the first operand.
  93. * @param op2 the second operand
  94. */
  95. public RelativeNumericProperty(int operation, Numeric op1, Numeric op2) {
  96. this.operation = operation;
  97. this.op1 = op1;
  98. this.op2 = op2;
  99. // Calculate the dimension. We can do now.
  100. switch (operation) {
  101. case MULTIPLY:
  102. dimension = op1.getDimension() + op2.getDimension();
  103. break;
  104. case DIVIDE:
  105. dimension = op1.getDimension() - op2.getDimension();
  106. break;
  107. default:
  108. dimension = op1.getDimension();
  109. }
  110. }
  111. /**
  112. * Constructor for a one argument operation.
  113. * @param operation the operation opcode: NEGATE, ABS
  114. * @param op the operand.
  115. */
  116. public RelativeNumericProperty(int operation, Numeric op) {
  117. this.operation = operation;
  118. this.op1 = op;
  119. this.dimension = op.getDimension();
  120. }
  121. /**
  122. * Return a resolved (calculated) Numeric with the value of the expression.
  123. * @throws PropertyException when an exception occur during evaluation.
  124. */
  125. private Numeric getResolved() throws PropertyException {
  126. Numeric n;
  127. switch (operation) {
  128. case ADDITION:
  129. return NumericOp.addition2(op1, op2);
  130. case SUBTRACTION:
  131. return NumericOp.subtraction2(op1, op2);
  132. case MULTIPLY:
  133. return NumericOp.multiply2(op1, op2);
  134. case DIVIDE:
  135. return NumericOp.divide2(op1, op2);
  136. case MODULO:
  137. return NumericOp.modulo2(op1, op2);
  138. case NEGATE:
  139. return NumericOp.negate2(op1);
  140. case ABS:
  141. return NumericOp.abs2(op1);
  142. case MAX:
  143. return NumericOp.max2(op1, op2);
  144. case MIN:
  145. return NumericOp.min2(op1, op2);
  146. default:
  147. throw new PropertyException("Unknown expr operation " + operation);
  148. }
  149. }
  150. /**
  151. * Return the resolved (calculated) value of the expression.
  152. * @see Numeric#getNumericValue()
  153. */
  154. public double getNumericValue() throws PropertyException {
  155. return getResolved().getNumericValue();
  156. }
  157. /**
  158. * Return the dimension of the expression
  159. */
  160. public int getDimension() {
  161. return dimension;
  162. }
  163. /**
  164. * Return false since an expression is only created when there is relative
  165. * numerics involved.
  166. */
  167. public boolean isAbsolute() {
  168. return false;
  169. }
  170. /**
  171. * Cast this numeric as a Length.
  172. */
  173. public Length getLength() {
  174. if (dimension == 1) {
  175. return this;
  176. }
  177. System.err.print("Can't create length with dimension " + dimension);
  178. return null;
  179. }
  180. public Numeric getNumeric() {
  181. return this;
  182. }
  183. /**
  184. * Return a resolved length.
  185. */
  186. public int getValue() {
  187. try {
  188. return (int) getNumericValue();
  189. } catch (PropertyException exc) {
  190. exc.printStackTrace();
  191. }
  192. return 0;
  193. }
  194. /**
  195. * Return false, since a numeric is never the "auto" enum.
  196. */
  197. public boolean isAuto() {
  198. return false;
  199. }
  200. /**
  201. * Return a string represention of the expression. Only used for debugging.
  202. */
  203. public String toString() {
  204. switch (operation) {
  205. case ADDITION: case SUBTRACTION:
  206. case DIVIDE: case MULTIPLY: case MODULO:
  207. return "(" + op1 + " " + operations.charAt(operation) + op2 + ")";
  208. case NEGATE:
  209. return "-" + op1;
  210. case MAX:
  211. return "max(" + op1 + ", " + op2 + ")";
  212. case MIN:
  213. return "min(" + op1 + ", " + op2 + ")";
  214. case ABS:
  215. return "abs(" + op1 + ")";
  216. }
  217. return "unknown operation " + operation;
  218. }
  219. }