1 51 package org.apache.fop.fo.expr; 52 53 import org.apache.fop.datatypes.Length; 54 import org.apache.fop.datatypes.FixedLength; 55 import org.apache.fop.datatypes.PercentLength; 56 import org.apache.fop.datatypes.MixedLength; 57 import org.apache.fop.datatypes.TableColLength; 58 import org.apache.fop.datatypes.PercentBase; 59 60 import java.util.ArrayList ; 61 62 73 public class Numeric { 74 public static final int ABS_LENGTH = 1; public static final int PC_LENGTH = 2; public static final int TCOL_LENGTH = 4; 79 private int valType; 80 private double absValue; 81 private double pcValue; 82 private PercentBase pcBase = null; private double tcolValue; 84 private int dim; 85 86 87 101 protected Numeric(int valType, double absValue, double pcValue, 102 double tcolValue, int dim, PercentBase pcBase) { 103 this.valType = valType; 104 this.absValue = absValue; 105 this.pcValue = pcValue; 106 this.tcolValue = tcolValue; 107 this.dim = dim; 108 this.pcBase = pcBase; 109 } 110 111 116 117 124 125 129 public Numeric(Number num) { 130 this(ABS_LENGTH, num.doubleValue(), 0.0, 0.0, 0, null); 131 } 132 133 137 public Numeric(FixedLength l) { 138 this(ABS_LENGTH, (double)l.mvalue(), 0.0, 0.0, 1, null); 139 } 140 141 145 public Numeric(PercentLength pclen) { 146 this(PC_LENGTH, 0.0, pclen.value(), 0.0, 1, pclen.getBaseLength()); 147 } 148 149 153 public Numeric(TableColLength tclen) { 154 this(TCOL_LENGTH, 0.0, 0.0, tclen.getTableUnits(), 1, null); 155 } 156 157 158 165 public Length asLength() { 166 if (dim == 1) { 167 ArrayList len = new ArrayList (3); 168 if ((valType & ABS_LENGTH) != 0) { 169 len.add(new FixedLength((int)absValue)); 170 } 171 if ((valType & PC_LENGTH) != 0) { 172 len.add(new PercentLength(pcValue, pcBase)); 173 } 174 if ((valType & TCOL_LENGTH) != 0) { 175 len.add(new TableColLength(tcolValue)); 176 } 177 if (len.size() == 1) { 178 return (Length)len.get(0); 179 } else { 180 return new MixedLength(len); 181 } 182 } else { 183 return null; 186 } 187 } 188 189 193 public Number asNumber() { 194 return asDouble(); 195 } 196 197 public Double asDouble() { 198 if (dim == 0 && valType == ABS_LENGTH) { 199 return new Double (absValue); 200 } else { 201 return null; 204 } 205 } 206 207 213 214 226 227 232 private boolean isMixedType() { 233 int ntype = 0; 234 for (int t = valType; t != 0; t = t >> 1) { 235 if ((t & 1) != 0) 236 ++ntype; 237 } 238 return ntype > 1; 239 } 240 241 249 public Numeric subtract(Numeric op) throws PropertyException { 250 if (dim == op.dim) { 255 PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase 256 : op.pcBase; 257 return new Numeric(valType | op.valType, absValue - op.absValue, 259 pcValue - op.pcValue, 260 tcolValue - op.tcolValue, dim, npcBase); 261 } else { 262 throw new PropertyException("Can't add Numerics of different dimensions"); 263 } 264 } 265 266 274 public Numeric add(Numeric op) throws PropertyException { 275 if (dim == op.dim) { 280 PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase 281 : op.pcBase; 282 return new Numeric(valType | op.valType, absValue + op.absValue, 284 pcValue + op.pcValue, 285 tcolValue + op.tcolValue, dim, npcBase); 286 } else { 287 throw new PropertyException("Can't add Numerics of different dimensions"); 288 } 289 } 290 291 298 public Numeric multiply(Numeric op) throws PropertyException { 299 if (dim == 0) { 303 return new Numeric(op.valType, absValue * op.absValue, 305 absValue * op.pcValue, 306 absValue * op.tcolValue, op.dim, op.pcBase); 307 } else if (op.dim == 0) { 308 double opval = op.absValue; 309 return new Numeric(valType, opval * absValue, opval * pcValue, 310 opval * tcolValue, dim, pcBase); 311 } else if (valType == op.valType &&!isMixedType()) { 312 PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase 314 : op.pcBase; 315 return new Numeric(valType, absValue * op.absValue, 316 pcValue * op.pcValue, 317 tcolValue * op.tcolValue, dim + op.dim, 318 npcBase); 319 } else { 320 throw new PropertyException("Can't multiply mixed Numerics"); 321 } 322 } 323 324 331 public Numeric divide(Numeric op) throws PropertyException { 332 if (dim == 0) { 336 return new Numeric(op.valType, absValue / op.absValue, 338 absValue / op.pcValue, 339 absValue / op.tcolValue, -op.dim, op.pcBase); 340 } else if (op.dim == 0) { 341 double opval = op.absValue; 342 return new Numeric(valType, absValue / opval, pcValue / opval, 343 tcolValue / opval, dim, pcBase); 344 } else if (valType == op.valType &&!isMixedType()) { 345 PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase 346 : op.pcBase; 347 return new Numeric(valType, 348 (valType == ABS_LENGTH ? absValue / op.absValue : 0.0), 349 (valType == PC_LENGTH ? pcValue / op.pcValue : 0.0), 350 (valType == TCOL_LENGTH ? tcolValue / op.tcolValue : 0.0), 351 dim - op.dim, npcBase); 352 } else { 353 throw new PropertyException("Can't divide mixed Numerics."); 354 } 355 } 356 357 361 public Numeric abs() { 362 return new Numeric(valType, Math.abs(absValue), Math.abs(pcValue), 363 Math.abs(tcolValue), dim, pcBase); 364 } 365 366 372 public Numeric max(Numeric op) throws PropertyException { 373 double rslt = 0.0; 374 if (dim == op.dim && valType == op.valType &&!isMixedType()) { 376 if (valType == ABS_LENGTH) 377 rslt = absValue - op.absValue; 378 else if (valType == PC_LENGTH) 379 rslt = pcValue - op.pcValue; 380 else if (valType == TCOL_LENGTH) 381 rslt = tcolValue - op.tcolValue; 382 if (rslt > 0.0) 383 return this; 384 else 385 return op; 386 } 387 throw new PropertyException("Arguments to max() must have same dimension and value type."); 388 } 389 390 396 public Numeric min(Numeric op) throws PropertyException { 397 double rslt = 0.0; 398 if (dim == op.dim && valType == op.valType &&!isMixedType()) { 400 if (valType == ABS_LENGTH) 401 rslt = absValue - op.absValue; 402 else if (valType == PC_LENGTH) 403 rslt = pcValue - op.pcValue; 404 else if (valType == TCOL_LENGTH) 405 rslt = tcolValue - op.tcolValue; 406 if (rslt > 0.0) 407 return op; 408 else 409 return this; 410 } 411 throw new PropertyException("Arguments to min() must have same dimension and value type."); 412 } 413 414 } 415 | Popular Tags |