/* * 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. */ package org.apache.pdfbox.pdmodel.common.function.type4; import java.util.Stack; /** * Provides the arithmetic operators such as "add" and "sub". * */ class ArithmeticOperators { /** Implements the "abs" operator. */ static class Abs implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { context.getStack().push(Math.abs(num.intValue())); } else { context.getStack().push(Math.abs(num.floatValue())); } } } /** Implements the "add" operator. */ static class Add implements Operator { public void execute(ExecutionContext context) { Number num2 = context.popNumber(); Number num1 = context.popNumber(); if (num1 instanceof Integer && num2 instanceof Integer) { long sum = num1.longValue() + num2.longValue(); if (sum < Integer.MIN_VALUE || sum > Integer.MAX_VALUE) { context.getStack().push((float) sum); } else { context.getStack().push((int)sum); } } else { float sum = num1.floatValue() + num2.floatValue(); context.getStack().push(sum); } } } /** Implements the "atan" operator. */ static class Atan implements Operator { public void execute(ExecutionContext context) { float den = context.popReal(); float num = context.popReal(); float atan = (float)Math.atan2(num, den); atan = (float)Math.toDegrees(atan) % 360; if (atan < 0) { atan = atan + 360; } context.getStack().push(atan); } } /** Implements the "ceiling" operator. */ static class Ceiling implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { context.getStack().push(num); } else { context.getStack().push((float)Math.ceil(num.doubleValue())); } } } /** Implements the "cos" operator. */ static class Cos implements Operator { public void execute(ExecutionContext context) { float angle = context.popReal(); float cos = (float)Math.cos(Math.toRadians(angle)); context.getStack().push(cos); } } /** Implements the "cvi" operator. */ static class Cvi implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); context.getStack().push(num.intValue()); } } /** Implements the "cvr" operator. */ static class Cvr implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); context.getStack().push(num.floatValue()); } } /** Implements the "div" operator. */ static class Div implements Operator { public void execute(ExecutionContext context) { Number num2 = context.popNumber(); Number num1 = context.popNumber(); context.getStack().push(num1.floatValue() / num2.floatValue()); } } /** Implements the "exp" operator. */ static class Exp implements Operator { public void execute(ExecutionContext context) { Number exp = context.popNumber(); Number base = context.popNumber(); double value = Math.pow(base.doubleValue(), exp.doubleValue()); context.getStack().push((float)value); } } /** Implements the "floor" operator. */ static class Floor implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { context.getStack().push(num); } else { context.getStack().push((float)Math.floor(num.doubleValue())); } } } /** Implements the "idiv" operator. */ static class IDiv implements Operator { public void execute(ExecutionContext context) { int num2 = context.popInt(); int num1 = context.popInt(); context.getStack().push(num1 / num2); } } /** Implements the "ln" operator. */ static class Ln implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); context.getStack().push((float)Math.log(num.doubleValue())); } } /** Implements the "log" operator. */ static class Log implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); context.getStack().push((float)Math.log10(num.doubleValue())); } } /** Implements the "mod" operator. */ static class Mod implements Operator { public void execute(ExecutionContext context) { int int2 = context.popInt(); int int1 = context.popInt(); context.getStack().push(int1 % int2); } } /** Implements the "mul" operator. */ static class Mul implements Operator { public void execute(ExecutionContext context) { Number num2 = context.popNumber(); Number num1 = context.popNumber(); if (num1 instanceof Integer && num2 instanceof Integer) { long result = num1.longValue() * num2.longValue(); if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) { context.getStack().push((int)result); } else { context.getStack().push((float)result); } } else { double result = num1.doubleValue() * num2.doubleValue(); context.getStack().push((float)result); } } } /** Implements the "neg" operator. */ static class Neg implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { int v = num.intValue(); if (v == Integer.MIN_VALUE) { context.getStack().push(-num.floatValue()); } else { context.getStack().push(-num.intValue()); } } else { context.getStack().push(-num.floatValue()); } } } /** Implements the "round" operator. */ static class Round implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { context.getStack().push(num.intValue()); } else { context.getStack().push((float)Math.round(num.doubleValue())); } } } /** Implements the "sin" operator. */ static class Sin implements Operator { public void execute(ExecutionContext context) { float angle = context.popReal(); float sin = (float)Math.sin(Math.toRadians(angle)); context.getStack().push(sin); } } /** Implements the "sqrt" operator. */ static class Sqrt implements Operator { public void execute(ExecutionContext context) { float num = context.popReal(); if (num < 0) { throw new IllegalArgumentException("argument must be nonnegative"); } context.getStack().push((float)Math.sqrt(num)); } } /** Implements the "sub" operator. */ static class Sub implements Operator { public void execute(ExecutionContext context) { Stack<Object> stack = context.getStack(); Number num2 = context.popNumber(); Number num1 = context.popNumber(); if (num1 instanceof Integer && num2 instanceof Integer) { long result = num1.longValue() - num2.longValue(); if (result < Integer.MIN_VALUE || result > Integer.MAX_VALUE) { stack.push((float) result); } else { stack.push((int)result); } } else { float result = num1.floatValue() - num2.floatValue(); stack.push(result); } } } /** Implements the "truncate" operator. */ static class Truncate implements Operator { public void execute(ExecutionContext context) { Number num = context.popNumber(); if (num instanceof Integer) { context.getStack().push(num.intValue()); } else { context.getStack().push((float)(int)(num.floatValue())); } } } }