You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NumberProperty.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fo.properties;
  19. import java.awt.Color;
  20. import org.apache.fop.apps.FOUserAgent;
  21. import org.apache.fop.datatypes.Length;
  22. import org.apache.fop.datatypes.Numeric;
  23. import org.apache.fop.datatypes.PercentBaseContext;
  24. import org.apache.fop.fo.FObj;
  25. import org.apache.fop.fo.PropertyList;
  26. import org.apache.fop.fo.expr.PropertyException;
  27. import org.apache.fop.util.CompareUtil;
  28. /**
  29. * Class for handling numeric properties
  30. */
  31. public final class NumberProperty extends Property implements Numeric {
  32. /**
  33. * Inner class for making NumberProperty objects
  34. */
  35. public static class Maker extends PropertyMaker {
  36. /**
  37. * Constructor for NumberProperty.Maker
  38. * @param propId the id of the property for which a Maker should be created
  39. */
  40. public Maker(int propId) {
  41. super(propId);
  42. }
  43. /**
  44. * {@inheritDoc}
  45. */
  46. public Property convertProperty(Property p,
  47. PropertyList propertyList, FObj fo)
  48. throws PropertyException {
  49. if (p instanceof NumberProperty) {
  50. return p;
  51. }
  52. if (p instanceof EnumProperty) {
  53. return EnumNumber.getInstance(p);
  54. }
  55. Number val = p.getNumber();
  56. if (val != null) {
  57. return getInstance(val.doubleValue());
  58. }
  59. return convertPropertyDatatype(p, propertyList, fo);
  60. }
  61. }
  62. /**
  63. * A positive integer property maker.
  64. */
  65. public static class PositiveIntegerMaker extends PropertyMaker {
  66. /**
  67. * Constructor for NumberProperty.PositiveIntegerMaker
  68. * @param propId the id of the property for which a PositiveIntegerMaker should be created
  69. */
  70. public PositiveIntegerMaker(int propId) {
  71. super(propId);
  72. }
  73. /**
  74. * If the value is not positive, return a property with value 1
  75. *
  76. * {@inheritDoc}
  77. */
  78. public Property convertProperty(Property p,
  79. PropertyList propertyList, FObj fo)
  80. throws PropertyException {
  81. if (p instanceof EnumProperty) {
  82. return EnumNumber.getInstance(p);
  83. }
  84. Number val = p.getNumber();
  85. if (val != null) {
  86. int i = Math.round(val.floatValue());
  87. if (i <= 0) {
  88. i = 1;
  89. }
  90. return getInstance(i);
  91. }
  92. return convertPropertyDatatype(p, propertyList, fo);
  93. }
  94. }
  95. /** cache holding all canonical NumberProperty instances */
  96. private static final PropertyCache<NumberProperty> CACHE
  97. = new PropertyCache<NumberProperty>();
  98. private final Number number;
  99. /**
  100. * Constructor for double input
  101. * @param num double numeric value for property
  102. */
  103. private NumberProperty(double num) {
  104. //Store the number as an int or a long,
  105. //if possible
  106. if (num == Math.floor(num)) {
  107. if (num < Integer.MAX_VALUE) {
  108. this.number = (int) num;
  109. } else {
  110. this.number = (long) num;
  111. }
  112. } else {
  113. this.number = num;
  114. }
  115. }
  116. /**
  117. * Constructor for integer input
  118. * @param num integer numeric value for property
  119. */
  120. private NumberProperty(int num) {
  121. this.number = num;
  122. }
  123. /**
  124. * Returns the canonical NumberProperty instance
  125. * corresponding to the given Number
  126. * @param num the base Double
  127. * @return the canonical NumberProperty
  128. */
  129. public static NumberProperty getInstance(Double num) {
  130. return CACHE.fetch(new NumberProperty(num));
  131. }
  132. /**
  133. * Returns the canonical NumberProperty instance
  134. * corresponding to the given Integer
  135. * @param num the base Integer
  136. * @return the canonical NumberProperty
  137. */
  138. public static NumberProperty getInstance(Integer num) {
  139. return CACHE.fetch(new NumberProperty(num));
  140. }
  141. /**
  142. * Returns the canonical NumberProperty instance
  143. * corresponding to the given double
  144. * @param num the base double value
  145. * @return the canonical NumberProperty
  146. */
  147. public static NumberProperty getInstance(double num) {
  148. return CACHE.fetch(new NumberProperty(num));
  149. }
  150. /**
  151. * Returns the canonical NumberProperty instance
  152. * corresponding to the given int
  153. * @param num the base int value
  154. * @return the canonical NumberProperty
  155. */
  156. public static NumberProperty getInstance(int num) {
  157. return CACHE.fetch(new NumberProperty(num));
  158. }
  159. /**
  160. * Plain number always has a dimension of 0.
  161. * @return a dimension of 0.
  162. */
  163. public int getDimension() {
  164. return 0;
  165. }
  166. /**
  167. * Return the value of this Numeric.
  168. * @return The value as a double.
  169. */
  170. public double getNumericValue() {
  171. return number.doubleValue();
  172. }
  173. /**
  174. * Return the value of this Numeric.
  175. * @param context Evaluation context
  176. * @return The value as a double.
  177. */
  178. public double getNumericValue(PercentBaseContext context) {
  179. return getNumericValue();
  180. }
  181. /** {@inheritDoc} */
  182. public int getValue() {
  183. return number.intValue();
  184. }
  185. /**
  186. * Return the value
  187. * @param context Evaluation context
  188. * @return The value as an int.
  189. */
  190. public int getValue(PercentBaseContext context) {
  191. return getValue();
  192. }
  193. /**
  194. * Return true because all numbers are absolute.
  195. * @return true.
  196. */
  197. public boolean isAbsolute() {
  198. return true;
  199. }
  200. /**
  201. * @return this.number cast as a Number
  202. */
  203. public Number getNumber() {
  204. return this.number;
  205. }
  206. /**
  207. * @return this.number cast as an Object
  208. */
  209. public Object getObject() {
  210. return this.number;
  211. }
  212. /**
  213. * Convert NumberProperty to Numeric object
  214. * @return Numeric object corresponding to this
  215. */
  216. public Numeric getNumeric() {
  217. return this;
  218. }
  219. /** {@inheritDoc} */
  220. public Length getLength() {
  221. //Assume pixels (like in HTML) when there's no unit
  222. return FixedLength.getInstance(getNumericValue(), "px");
  223. }
  224. /**
  225. * Convert NumberProperty to a Color. Not sure why this is needed.
  226. * @param foUserAgent FOUserAgent
  227. * @return Color that corresponds to black
  228. */
  229. public Color getColor(FOUserAgent foUserAgent) {
  230. // TODO: Implement somehow
  231. // Convert numeric value to color ???
  232. // Convert to hexadecimal and then try to make it into a color?
  233. return Color.black;
  234. }
  235. /** {@inheritDoc} */
  236. @Override
  237. public boolean equals(Object obj) {
  238. if (this == obj) {
  239. return true;
  240. }
  241. if (!(obj instanceof NumberProperty)) {
  242. return false;
  243. }
  244. NumberProperty other = (NumberProperty) obj;
  245. return CompareUtil.equal(number, other.number);
  246. }
  247. /** {@inheritDoc} */
  248. @Override
  249. public int hashCode() {
  250. return number.hashCode();
  251. }
  252. }