You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by je...@apache.org on 2011/10/18 17:23:57 UTC
svn commit: r1185719 [1/2] - in /pdfbox/trunk/pdfbox/src:
main/java/org/apache/pdfbox/pdmodel/common/function/
main/java/org/apache/pdfbox/pdmodel/common/function/type4/
main/java/org/apache/pdfbox/pdmodel/graphics/color/
test/java/org/apache/pdfbox/ t...
Author: jeremias
Date: Tue Oct 18 15:23:56 2011
New Revision: 1185719
URL: http://svn.apache.org/viewvc?rev=1185719&view=rev
Log:
PDFBOX-1142: Added support for Type 4 functions.
Added:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java (with props)
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/package.html (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/type4/
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/type4/TestOperators.java (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/type4/TestParser.java (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/type4/Type4Tester.java (with props)
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html (with props)
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType4.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceN.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDSeparation.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestAll.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType4.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType4.java?rev=1185719&r1=1185718&r2=1185719&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType4.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/PDFunctionType4.java Tue Oct 18 15:23:56 2011
@@ -18,26 +18,39 @@ package org.apache.pdfbox.pdmodel.common
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.pdmodel.common.function.type4.ExecutionContext;
+import org.apache.pdfbox.pdmodel.common.function.type4.InstructionSequence;
+import org.apache.pdfbox.pdmodel.common.function.type4.InstructionSequenceBuilder;
+import org.apache.pdfbox.pdmodel.common.function.type4.Operators;
import java.io.IOException;
/**
* This class represents a type 4 function in a PDF document.
+ * <p>
+ * See section 3.9.4 of the PDF 1.4 Reference.
*
- * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
* @version $Revision: 1.2 $
*/
public class PDFunctionType4 extends PDFunction
{
+ private static final Operators OPERATORS = new Operators();
+
+ private final InstructionSequence instructions;
+
/**
* Constructor.
*
- * @param functionStream The function .
+ * @param functionStream The function stream.
+ * @throws IOException if an I/O error occurs while reading the function
*/
- public PDFunctionType4(COSBase function)
+ public PDFunctionType4(COSBase functionStream) throws IOException
{
- super( function );
+ super( functionStream );
+ this.instructions = InstructionSequenceBuilder.parse(
+ getPDStream().getInputStreamAsString());
}
@@ -54,8 +67,41 @@ public class PDFunctionType4 extends PDF
*/
public COSArray eval(COSArray input) throws IOException
{
- //Implementation here will require evaluation of PostScript functions.
- //See section 3.9.4 of the PDF Reference.
- throw new IOException("Not Implemented");
+ //Setup the input values
+ float[] inputValues = input.toFloatArray();
+ int numberOfInputValues = inputValues.length;
+ ExecutionContext context = new ExecutionContext(OPERATORS);
+ for (int i = numberOfInputValues - 1; i >= 0; i--)
+ {
+ PDRange domain = getDomainForInput(i);
+ float value = clipToRange(inputValues[i], domain.getMin(), domain.getMax());
+ context.getStack().push(value);
+ }
+
+ //Execute the type 4 function.
+ instructions.execute(context);
+
+ //Extract the output values
+ int numberOfOutputValues = getNumberOfOutputParameters();
+ int numberOfActualOutputValues = context.getStack().size();
+ if (numberOfActualOutputValues < numberOfOutputValues)
+ {
+ throw new IllegalStateException("The type 4 function returned "
+ + numberOfActualOutputValues
+ + " values but the Range entry indicates that "
+ + numberOfOutputValues + " values be returned.");
+ }
+ float[] outputValues = new float[numberOfOutputValues];
+ for (int i = numberOfOutputValues - 1; i >= 0; i--)
+ {
+ PDRange range = getRangeForOutput(i);
+ outputValues[i] = context.popReal();
+ outputValues[i] = clipToRange(outputValues[i], range.getMin(), range.getMax());
+ }
+
+ //Return the resulting array
+ COSArray result = new COSArray();
+ result.setFloatArray(outputValues);
+ return result;
}
}
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,401 @@
+/*
+ * 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".
+ *
+ * @version $Revision$
+ */
+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.valueOf(sum));
+ }
+ else
+ {
+ context.getStack().push(Integer.valueOf((int)sum));
+ }
+ }
+ else
+ {
+ float sum = num1.floatValue() + num2.floatValue();
+ context.getStack().push(Float.valueOf(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.valueOf(result));
+ }
+ else
+ {
+ stack.push(Integer.valueOf((int)result));
+ }
+ }
+ else
+ {
+ float result = num1.floatValue() - num2.floatValue();
+ stack.push(Float.valueOf(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()));
+ }
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ArithmeticOperators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,193 @@
+/*
+ * 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 bitwise operators such as "and" and "xor".
+ *
+ * @version $Revision$
+ */
+class BitwiseOperators
+{
+
+ /** Abstract base class for logical operators. */
+ private abstract static class AbstractLogicalOperator implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ Object op2 = stack.pop();
+ Object op1 = stack.pop();
+ if (op1 instanceof Boolean && op2 instanceof Boolean)
+ {
+ boolean bool1 = (Boolean)op1;
+ boolean bool2 = (Boolean)op2;
+ boolean result = applyForBoolean(bool1, bool2);
+ stack.push(result);
+ }
+ else if (op1 instanceof Integer && op2 instanceof Integer)
+ {
+ int int1 = (Integer)op1;
+ int int2 = (Integer)op2;
+ int result = applyforInteger(int1, int2);
+ stack.push(result);
+ }
+ else
+ {
+ throw new ClassCastException("Operands must be bool/bool or int/int");
+ }
+ }
+
+
+ protected abstract boolean applyForBoolean(boolean bool1, boolean bool2);
+
+ protected abstract int applyforInteger(int int1, int int2);
+
+ }
+
+ /** Implements the "and" operator. */
+ static class And extends AbstractLogicalOperator
+ {
+
+ @Override
+ protected boolean applyForBoolean(boolean bool1, boolean bool2)
+ {
+ return bool1 & bool2;
+ }
+
+ @Override
+ protected int applyforInteger(int int1, int int2)
+ {
+ return int1 & int2;
+ }
+ }
+
+ /** Implements the "bitshift" operator. */
+ static class Bitshift implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ int shift = (Integer)stack.pop();
+ int int1 = (Integer)stack.pop();
+ if (shift < 0)
+ {
+ int result = int1 >> Math.abs(shift);
+ stack.push(result);
+ }
+ else
+ {
+ int result = int1 << shift;
+ stack.push(result);
+ }
+ }
+
+ }
+
+ /** Implements the "false" operator. */
+ static class False implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ stack.push(Boolean.FALSE);
+ }
+
+ }
+
+ /** Implements the "not" operator. */
+ static class Not implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ Object op1 = stack.pop();
+ if (op1 instanceof Boolean)
+ {
+ boolean bool1 = (Boolean)op1;
+ boolean result = !bool1;
+ stack.push(result);
+ }
+ else if (op1 instanceof Integer)
+ {
+ int int1 = (Integer)op1;
+ int result = -int1;
+ stack.push(result);
+ }
+ else
+ {
+ throw new ClassCastException("Operand must be bool or int");
+ }
+ }
+
+ }
+
+ /** Implements the "or" operator. */
+ static class Or extends AbstractLogicalOperator
+ {
+
+ @Override
+ protected boolean applyForBoolean(boolean bool1, boolean bool2)
+ {
+ return bool1 | bool2;
+ }
+
+ @Override
+ protected int applyforInteger(int int1, int int2)
+ {
+ return int1 | int2;
+ }
+
+ }
+
+ /** Implements the "true" operator. */
+ static class True implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ stack.push(Boolean.TRUE);
+ }
+
+ }
+
+ /** Implements the "xor" operator. */
+ static class Xor extends AbstractLogicalOperator
+ {
+
+ @Override
+ protected boolean applyForBoolean(boolean bool1, boolean bool2)
+ {
+ return bool1 ^ bool2;
+ }
+
+ @Override
+ protected int applyforInteger(int int1, int int2)
+ {
+ return int1 ^ int2;
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/BitwiseOperators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,68 @@
+/*
+ * 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 conditional operators such as "if" and "ifelse".
+ *
+ * @version $Revision$
+ */
+class ConditionalOperators
+{
+
+ /** Implements the "if" operator. */
+ static class If implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ InstructionSequence proc = (InstructionSequence)stack.pop();
+ Boolean condition = (Boolean)stack.pop();
+ if (condition)
+ {
+ proc.execute(context);
+ }
+ }
+
+ }
+
+ /** Implements the "ifelse" operator. */
+ static class IfElse implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ InstructionSequence proc2 = (InstructionSequence)stack.pop();
+ InstructionSequence proc1 = (InstructionSequence)stack.pop();
+ Boolean condition = (Boolean)stack.pop();
+ if (condition)
+ {
+ proc1.execute(context);
+ }
+ else
+ {
+ proc2.execute(context);
+ }
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ConditionalOperators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+/**
+ * Makes up the execution context, holding the available operators and the execution stack.
+ *
+ * @version $Revision$
+ */
+public class ExecutionContext
+{
+
+ private Operators operators;
+ private Stack<Object> stack = new Stack<Object>();
+
+ /**
+ * Creates a new execution context.
+ * @param operatorSet the operator set
+ */
+ public ExecutionContext(Operators operatorSet)
+ {
+ this.operators = operatorSet;
+ }
+
+ /**
+ * Returns the stack used by this execution context.
+ * @return the stack
+ */
+ public Stack<Object> getStack()
+ {
+ return this.stack;
+ }
+
+ /**
+ * Returns the operator set used by this execution context.
+ * @return the operator set
+ */
+ public Operators getOperators()
+ {
+ return this.operators;
+ }
+
+ /**
+ * Pops a number (int or real) from the stack. If it's neither data type, a
+ * ClassCastException is thrown.
+ * @return the number
+ */
+ public Number popNumber()
+ {
+ return (Number)stack.pop();
+ }
+
+ /**
+ * Pops a value of type int from the stack. If the value is not of type int, a
+ * ClassCastException is thrown.
+ * @return the int value
+ */
+ public int popInt()
+ {
+ return ((Integer)stack.pop()).intValue();
+ }
+
+ /**
+ * Pops a number from the stack and returns it as a real value. If the value is not of a
+ * numeric type, a ClassCastException is thrown.
+ * @return the real value
+ */
+ public float popReal()
+ {
+ return ((Number)stack.pop()).floatValue();
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/ExecutionContext.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,113 @@
+/*
+ * 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.List;
+import java.util.Stack;
+
+/**
+ * Represents an instruction sequence, a combination of values, operands and nested procedures.
+ *
+ * @version $Revision$
+ */
+public class InstructionSequence
+{
+
+ private List<Object> instructions = new java.util.ArrayList<Object>();
+
+ /**
+ * Add a name (ex. an operator)
+ * @param name the name
+ */
+ public void addName(String name)
+ {
+ this.instructions.add(name);
+ }
+
+ /**
+ * Adds an int value.
+ * @param value the value
+ */
+ public void addInteger(int value)
+ {
+ this.instructions.add(Integer.valueOf(value));
+ }
+
+ /**
+ * Adds a real value.
+ * @param value the value
+ */
+ public void addReal(float value)
+ {
+ this.instructions.add(Float.valueOf(value));
+ }
+
+ /**
+ * Adds a bool value.
+ * @param value the value
+ */
+ public void addBoolean(boolean value)
+ {
+ this.instructions.add(Boolean.valueOf(value));
+ }
+
+ /**
+ * Adds a proc (sub-sequence of instructions).
+ * @param child the child proc
+ */
+ public void addProc(InstructionSequence child)
+ {
+ this.instructions.add(child);
+ }
+
+ /**
+ * Executes the instruction sequence.
+ * @param context the execution context
+ */
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ for (Object o : instructions)
+ {
+ if (o instanceof String)
+ {
+ String name = (String)o;
+ Operator cmd = context.getOperators().getOperator(name);
+ if (cmd != null)
+ {
+ cmd.execute(context);
+ }
+ else
+ {
+ throw new UnsupportedOperationException("Unknown operator or name: " + name);
+ }
+ }
+ else
+ {
+ stack.push(o);
+ }
+ }
+
+ //Handles top-level procs that simply need to be executed
+ while (!stack.isEmpty() && stack.peek() instanceof InstructionSequence)
+ {
+ InstructionSequence nested = (InstructionSequence)stack.pop();
+ nested.execute(context);
+ }
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequence.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,134 @@
+/*
+ * 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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Basic parser for Type 4 functions which is used to build up instruction sequences.
+ *
+ * @version $Revision$
+ */
+public class InstructionSequenceBuilder extends Parser.AbstractSyntaxHandler
+{
+
+ private InstructionSequence mainSequence = new InstructionSequence();
+ private Stack<InstructionSequence> seqStack = new Stack<InstructionSequence>();
+
+ private InstructionSequenceBuilder()
+ {
+ this.seqStack.push(this.mainSequence);
+ }
+
+ /**
+ * Returns the instruction sequence that has been build from the syntactic elements.
+ * @return the instruction sequence
+ */
+ public InstructionSequence getInstructionSequence()
+ {
+ return this.mainSequence;
+ }
+
+ /**
+ * Parses the given text into an instruction sequence representing a Type 4 function
+ * that can be executed.
+ * @param text the Type 4 function text
+ * @return the instruction sequence
+ */
+ public static InstructionSequence parse(CharSequence text)
+ {
+ InstructionSequenceBuilder builder = new InstructionSequenceBuilder();
+ Parser.parse(text, builder);
+ return builder.getInstructionSequence();
+ }
+
+ private InstructionSequence getCurrentSequence()
+ {
+ return this.seqStack.peek();
+ }
+
+ private static final Pattern INTEGER_PATTERN = Pattern.compile("[\\+\\-]?\\d+");
+ private static final Pattern REAL_PATTERN = Pattern.compile("[\\-]?\\d*\\.\\d*([Ee]\\-?\\d+)?");
+
+ /** {@inheritDoc} */
+ public void token(CharSequence text)
+ {
+ String token = text.toString();
+ token(token);
+ }
+
+ private void token(String token)
+ {
+ if ("{".equals(token))
+ {
+ InstructionSequence child = new InstructionSequence();
+ getCurrentSequence().addProc(child);
+ this.seqStack.push(child);
+ }
+ else if ("}".equals(token))
+ {
+ this.seqStack.pop();
+ }
+ else
+ {
+ Matcher m = INTEGER_PATTERN.matcher(token);
+ if (m.matches())
+ {
+ getCurrentSequence().addInteger(parseInt(token.toString()));
+ return;
+ }
+
+ m = REAL_PATTERN.matcher(token);
+ if (m.matches())
+ {
+ getCurrentSequence().addReal(parseReal(token));
+ return;
+ }
+
+ //TODO Maybe implement radix numbers, such as 8#1777 or 16#FFFE
+
+ getCurrentSequence().addName(token.toString());
+ }
+ }
+
+ /**
+ * Parses a value of type "int".
+ * @param token the token to be parsed
+ * @return the parsed value
+ */
+ public static int parseInt(String token)
+ {
+ if (token.startsWith("+"))
+ {
+ token = token.substring(1);
+ }
+ return Integer.parseInt(token);
+ }
+
+ /**
+ * Parses a value of type "real".
+ * @param token the token to be parsed
+ * @return the parsed value
+ */
+ public static float parseReal(String token)
+ {
+ return Float.parseFloat(token);
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/InstructionSequenceBuilder.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Interface for PostScript operators.
+ *
+ * @version $Revision$
+ */
+public interface Operator
+{
+
+ /**
+ * Executes the operator. The method can inspect and manipulate the stack.
+ * @param context the execution context
+ */
+ void execute(ExecutionContext context);
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operator.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,142 @@
+/*
+ * 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.Map;
+
+/**
+ * This class provides all the supported operators.
+ * @version $Revision$
+ */
+public class Operators
+{
+
+ //Arithmetic operators
+ private static final Operator ABS = new ArithmeticOperators.Abs();
+ private static final Operator ADD = new ArithmeticOperators.Add();
+ private static final Operator ATAN = new ArithmeticOperators.Atan();
+ private static final Operator CEILING = new ArithmeticOperators.Ceiling();
+ private static final Operator COS = new ArithmeticOperators.Cos();
+ private static final Operator CVI = new ArithmeticOperators.Cvi();
+ private static final Operator CVR = new ArithmeticOperators.Cvr();
+ private static final Operator DIV = new ArithmeticOperators.Div();
+ private static final Operator EXP = new ArithmeticOperators.Exp();
+ private static final Operator FLOOR = new ArithmeticOperators.Floor();
+ private static final Operator IDIV = new ArithmeticOperators.IDiv();
+ private static final Operator LN = new ArithmeticOperators.Ln();
+ private static final Operator LOG = new ArithmeticOperators.Log();
+ private static final Operator MOD = new ArithmeticOperators.Mod();
+ private static final Operator MUL = new ArithmeticOperators.Mul();
+ private static final Operator NEG = new ArithmeticOperators.Neg();
+ private static final Operator ROUND = new ArithmeticOperators.Round();
+ private static final Operator SIN = new ArithmeticOperators.Sin();
+ private static final Operator SQRT = new ArithmeticOperators.Sqrt();
+ private static final Operator SUB = new ArithmeticOperators.Sub();
+ private static final Operator TRUNCATE = new ArithmeticOperators.Truncate();
+
+ //Relational, boolean and bitwise operators
+ private static final Operator AND = new BitwiseOperators.And();
+ private static final Operator BITSHIFT = new BitwiseOperators.Bitshift();
+ private static final Operator EQ = new RelationalOperators.Eq();
+ private static final Operator FALSE = new BitwiseOperators.False();
+ private static final Operator GE = new RelationalOperators.Ge();
+ private static final Operator GT = new RelationalOperators.Gt();
+ private static final Operator LE = new RelationalOperators.Le();
+ private static final Operator LT = new RelationalOperators.Lt();
+ private static final Operator NE = new RelationalOperators.Ne();
+ private static final Operator NOT = new BitwiseOperators.Not();
+ private static final Operator OR = new BitwiseOperators.Or();
+ private static final Operator TRUE = new BitwiseOperators.True();
+ private static final Operator XOR = new BitwiseOperators.Xor();
+
+ //Conditional operators
+ private static final Operator IF = new ConditionalOperators.If();
+ private static final Operator IFELSE = new ConditionalOperators.IfElse();
+
+ //Stack operators
+ private static final Operator COPY = new StackOperators.Copy();
+ private static final Operator DUP = new StackOperators.Dup();
+ private static final Operator EXCH = new StackOperators.Exch();
+ private static final Operator INDEX = new StackOperators.Index();
+ private static final Operator POP = new StackOperators.Pop();
+ private static final Operator ROLL = new StackOperators.Roll();
+
+ private Map<String, Operator> operators = new java.util.HashMap<String, Operator>();
+
+ /**
+ * Creates a new Operators object with the default set of operators.
+ */
+ public Operators()
+ {
+ operators.put("add", ADD);
+ operators.put("abs", ABS);
+ operators.put("atan", ATAN);
+ operators.put("ceiling", CEILING);
+ operators.put("cos", COS);
+ operators.put("cvi", CVI);
+ operators.put("cvr", CVR);
+ operators.put("div", DIV);
+ operators.put("exp", EXP);
+ operators.put("floor", FLOOR);
+ operators.put("idiv", IDIV);
+ operators.put("ln", LN);
+ operators.put("log", LOG);
+ operators.put("mod", MOD);
+ operators.put("mul", MUL);
+ operators.put("neg", NEG);
+ operators.put("round", ROUND);
+ operators.put("sin", SIN);
+ operators.put("sqrt", SQRT);
+ operators.put("sub", SUB);
+ operators.put("truncate", TRUNCATE);
+
+ operators.put("and", AND);
+ operators.put("bitshift", BITSHIFT);
+ operators.put("eq", EQ);
+ operators.put("false", FALSE);
+ operators.put("ge", GE);
+ operators.put("gt", GT);
+ operators.put("le", LE);
+ operators.put("lt", LT);
+ operators.put("ne", NE);
+ operators.put("not", NOT);
+ operators.put("or", OR);
+ operators.put("true", TRUE);
+ operators.put("xor", XOR);
+
+ operators.put("if", IF);
+ operators.put("ifelse", IFELSE);
+
+ operators.put("copy", COPY);
+ operators.put("dup", DUP);
+ operators.put("exch", EXCH);
+ operators.put("index", INDEX);
+ operators.put("pop", POP);
+ operators.put("roll", ROLL);
+ }
+
+ /**
+ * Returns the operator for the given operator name.
+ * @param operatorName the operator name
+ * @return the operator (or null if there's no such operator
+ */
+ public Operator getOperator(String operatorName)
+ {
+ return this.operators.get(operatorName);
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Operators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,317 @@
+/*
+ * 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;
+
+/**
+ * Parser for PDF Type 4 functions. This implements a small subset of the PostScript
+ * language but is no full PostScript interpreter.
+ *
+ * @version $Revision$
+ */
+public class Parser
+{
+
+ /** Used to indicate the parsers current state. */
+ private static enum State
+ {
+ NEWLINE, WHITESPACE, COMMENT, TOKEN
+ }
+
+ private Parser()
+ {
+ //nop
+ }
+
+ /**
+ * Parses a Type 4 function and sends the syntactic elements to the given
+ * syntax handler.
+ * @param input the text source
+ * @param handler the syntax handler
+ */
+ public static void parse(CharSequence input, SyntaxHandler handler)
+ {
+ Tokenizer tokenizer = new Tokenizer(input, handler);
+ tokenizer.tokenize();
+ }
+
+ /**
+ * This interface defines all possible syntactic elements of a Type 4 function.
+ * It is called by the parser as the function is interpreted.
+ */
+ public interface SyntaxHandler
+ {
+
+ /**
+ * Indicates that a new line starts.
+ * @param text the new line character (CR, LF, CR/LF or FF)
+ */
+ void newLine(CharSequence text);
+
+ /**
+ * Called when whitespace characters are encountered.
+ * @param text the whitespace text
+ */
+ void whitespace(CharSequence text);
+
+ /**
+ * Called when a token is encountered. No distinction between operators and values
+ * is done here.
+ * @param text the token text
+ */
+ void token(CharSequence text);
+
+ /**
+ * Called for a comment.
+ * @param text the comment
+ */
+ void comment(CharSequence text);
+ }
+
+ /**
+ * Abstract base class for a {@link SyntaxHandler}.
+ */
+ public abstract static class AbstractSyntaxHandler implements SyntaxHandler
+ {
+
+ /** {@inheritDoc} */
+ public void comment(CharSequence text)
+ {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void newLine(CharSequence text)
+ {
+ //nop
+ }
+
+ /** {@inheritDoc} */
+ public void whitespace(CharSequence text)
+ {
+ //nop
+ }
+
+ }
+
+ /**
+ * Tokenizer for Type 4 functions.
+ */
+ private static class Tokenizer
+ {
+
+ private static final char NUL = '\u0000'; //NUL
+ private static final char EOT = '\u0004'; //END OF TRANSMISSION
+ private static final char TAB = '\u0009'; //TAB CHARACTER
+ private static final char FF = '\u000C'; //FORM FEED
+ private static final char CR = '\r'; //CARRIAGE RETURN
+ private static final char LF = '\n'; //LINE FEED
+ private static final char SPACE = '\u0020'; //SPACE
+
+ private CharSequence input;
+ private int index;
+ private SyntaxHandler handler;
+ private State state = State.WHITESPACE;
+ private StringBuilder buffer = new StringBuilder();
+
+ private Tokenizer(CharSequence text, SyntaxHandler syntaxHandler)
+ {
+ this.input = text;
+ this.handler = syntaxHandler;
+ }
+
+ private boolean hasMore()
+ {
+ return index < input.length();
+ }
+
+ private char currentChar()
+ {
+ return input.charAt(index);
+ }
+
+ private char nextChar()
+ {
+ index++;
+ if (!hasMore())
+ {
+ return EOT;
+ }
+ else
+ {
+ return currentChar();
+ }
+ }
+
+ private char peek()
+ {
+ if (index < input.length() - 1)
+ {
+ return input.charAt(index + 1);
+ }
+ else
+ {
+ return EOT;
+ }
+ }
+
+ private State nextState()
+ {
+ char ch = currentChar();
+ switch (ch)
+ {
+ case CR:
+ case LF:
+ case FF: //FF
+ state = State.NEWLINE;
+ break;
+ case NUL:
+ case TAB:
+ case SPACE:
+ state = State.WHITESPACE;
+ break;
+ case '%':
+ state = State.COMMENT;
+ break;
+ default:
+ state = State.TOKEN;
+ }
+ return state;
+ }
+
+ private void tokenize()
+ {
+ while (hasMore())
+ {
+ buffer.setLength(0);
+ nextState();
+ switch (state)
+ {
+ case NEWLINE:
+ scanNewLine();
+ break;
+ case WHITESPACE:
+ scanWhitespace();
+ break;
+ case COMMENT:
+ scanComment();
+ break;
+ default:
+ scanToken();
+ }
+ }
+ }
+
+ private void scanNewLine()
+ {
+ assert state == State.NEWLINE;
+ char ch = currentChar();
+ buffer.append(ch);
+ if (ch == CR)
+ {
+ if (peek() == LF)
+ {
+ //CRLF is treated as one newline
+ buffer.append(nextChar());
+ }
+ }
+ handler.newLine(buffer);
+ }
+
+ private void scanWhitespace()
+ {
+ assert state == State.WHITESPACE;
+ buffer.append(currentChar());
+ loop:
+ while (hasMore())
+ {
+ char ch = nextChar();
+ switch (ch)
+ {
+ case NUL:
+ case TAB:
+ case SPACE:
+ buffer.append(ch);
+ break;
+ default:
+ break loop;
+ }
+ }
+ handler.whitespace(buffer);
+ }
+
+ private void scanComment()
+ {
+ assert state == State.COMMENT;
+ buffer.append(currentChar());
+ loop:
+ while (hasMore())
+ {
+ char ch = nextChar();
+ switch (ch)
+ {
+ case CR:
+ case LF:
+ case FF:
+ break loop;
+ default:
+ buffer.append(ch);
+ }
+ }
+ //EOF reached
+ handler.comment(buffer);
+ }
+
+ private void scanToken()
+ {
+ assert state == State.TOKEN;
+ char ch = currentChar();
+ buffer.append(ch);
+ switch (ch)
+ {
+ case '{':
+ case '}':
+ handler.token(buffer);
+ nextChar();
+ return;
+ default:
+ //continue
+ }
+ loop:
+ while (hasMore())
+ {
+ ch = nextChar();
+ switch (ch)
+ {
+ case NUL:
+ case TAB:
+ case SPACE:
+ case CR:
+ case LF:
+ case FF:
+ case EOT:
+ break loop;
+ default:
+ buffer.append(ch);
+ }
+ }
+ //EOF reached
+ handler.token(buffer);
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/Parser.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,140 @@
+/*
+ * 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 relational operators such as "eq" and "le".
+ *
+ * @version $Revision$
+ */
+class RelationalOperators
+{
+
+ /** Implements the "eq" operator. */
+ static class Eq implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ Object op2 = stack.pop();
+ Object op1 = stack.pop();
+ boolean result = isEqual(op1, op2);
+ stack.push(result);
+ }
+
+ protected boolean isEqual(Object op1, Object op2)
+ {
+ boolean result = false;
+ if (op1 instanceof Number && op2 instanceof Number)
+ {
+ Number num1 = (Number)op1;
+ Number num2 = (Number)op2;
+ result = num1.floatValue() == num2.floatValue();
+ }
+ else
+ {
+ result = op1.equals(op2);
+ }
+ return result;
+ }
+
+ }
+
+ /** Abstract base class for number comparison operators. */
+ private abstract static class AbstractNumberComparisonOperator implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ Object op2 = stack.pop();
+ Object op1 = stack.pop();
+ Number num1 = (Number)op1;
+ Number num2 = (Number)op2;
+ boolean result = compare(num1, num2);
+ stack.push(result);
+ }
+
+ protected abstract boolean compare(Number num1, Number num2);
+
+ }
+
+ /** Implements the "ge" operator. */
+ static class Ge extends AbstractNumberComparisonOperator
+ {
+
+ @Override
+ protected boolean compare(Number num1, Number num2)
+ {
+ return num1.floatValue() >= num2.floatValue();
+ }
+
+ }
+
+ /** Implements the "gt" operator. */
+ static class Gt extends AbstractNumberComparisonOperator
+ {
+
+ @Override
+ protected boolean compare(Number num1, Number num2)
+ {
+ return num1.floatValue() > num2.floatValue();
+ }
+
+ }
+
+ /** Implements the "le" operator. */
+ static class Le extends AbstractNumberComparisonOperator
+ {
+
+ @Override
+ protected boolean compare(Number num1, Number num2)
+ {
+ return num1.floatValue() <= num2.floatValue();
+ }
+
+ }
+
+ /** Implements the "lt" operator. */
+ static class Lt extends AbstractNumberComparisonOperator
+ {
+
+ @Override
+ protected boolean compare(Number num1, Number num2)
+ {
+ return num1.floatValue() < num2.floatValue();
+ }
+
+ }
+
+ /** Implements the "ne" operator. */
+ static class Ne extends Eq
+ {
+
+ @Override
+ protected boolean isEqual(Object op1, Object op2)
+ {
+ boolean result = super.isEqual(op1, op2);
+ return !result;
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/RelationalOperators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,162 @@
+/*
+ * 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.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * Provides the stack operators such as "pop" and "dup".
+ *
+ * @version $Revision$
+ */
+class StackOperators
+{
+
+ /** Implements the "copy" operator. */
+ static class Copy implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ int n = ((Number)stack.pop()).intValue();
+ if (n > 0)
+ {
+ int size = stack.size();
+ //Need to copy to a new list to avoid ConcurrentModificationException
+ List<Object> copy = new java.util.ArrayList<Object>(
+ stack.subList(size - n, size));
+ stack.addAll(copy);
+ }
+ }
+
+ }
+
+ /** Implements the "dup" operator. */
+ static class Dup implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ stack.push(stack.peek());
+ }
+
+ }
+
+ /** Implements the "exch" operator. */
+ static class Exch implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ Object any2 = stack.pop();
+ Object any1 = stack.pop();
+ stack.push(any2);
+ stack.push(any1);
+ }
+
+ }
+
+ /** Implements the "index" operator. */
+ static class Index implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ int n = ((Number)stack.pop()).intValue();
+ if (n < 0)
+ {
+ throw new IllegalArgumentException("rangecheck: " + n);
+ }
+ int size = stack.size();
+ stack.push(stack.get(size - n - 1));
+ }
+
+ }
+
+ /** Implements the "pop" operator. */
+ static class Pop implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ stack.pop();
+ }
+
+ }
+
+ /** Implements the "roll" operator. */
+ static class Roll implements Operator
+ {
+
+ public void execute(ExecutionContext context)
+ {
+ Stack<Object> stack = context.getStack();
+ int j = ((Number)stack.pop()).intValue();
+ int n = ((Number)stack.pop()).intValue();
+ if (j == 0)
+ {
+ return; //Nothing to do
+ }
+ if (n < 0)
+ {
+ throw new IllegalArgumentException("rangecheck: " + n);
+ }
+
+ LinkedList<Object> rolled = new LinkedList<Object>();
+ LinkedList<Object> moved = new LinkedList<Object>();
+ if (j < 0)
+ {
+ //negative roll
+ int n1 = n + j;
+ for (int i = 0; i < n1; i++)
+ {
+ moved.addFirst(stack.pop());
+ }
+ for (int i = j; i < 0; i++)
+ {
+ rolled.addFirst(stack.pop());
+ }
+ stack.addAll(moved);
+ stack.addAll(rolled);
+ }
+ else
+ {
+ //positive roll
+ int n1 = n - j;
+ for (int i = j; i > 0; i--)
+ {
+ rolled.addFirst(stack.pop());
+ }
+ for (int i = 0; i < n1; i++)
+ {
+ moved.addFirst(stack.pop());
+ }
+ stack.addAll(rolled);
+ stack.addAll(moved);
+ }
+ }
+
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/StackOperators.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html Tue Oct 18 15:23:56 2011
@@ -0,0 +1,25 @@
+<!--
+ ! 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.
+ !-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package contains Type 4 function support.
+</body>
+</html>
Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/function/type4/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceN.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceN.java?rev=1185719&r1=1185718&r2=1185719&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceN.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceN.java Tue Oct 18 15:23:56 2011
@@ -27,13 +27,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSNull;
import org.apache.pdfbox.pdmodel.common.COSArrayList;
import org.apache.pdfbox.pdmodel.common.function.PDFunction;
-import org.apache.pdfbox.pdmodel.common.function.PDFunctionType4;
/**
* This class represents a DeviceN color space.
@@ -43,14 +41,14 @@ import org.apache.pdfbox.pdmodel.common.
*/
public class PDDeviceN extends PDColorSpace
{
-
+
/**
* Log instance.
*/
private static final Log LOG = LogFactory.getLog(PDDeviceN.class);
private static final int COLORANT_NAMES = 1;
-
+
private static final int ALTERNATE_CS = 2;
private static final int TINT_TRANSFORM = 3;
@@ -259,7 +257,7 @@ public class PDDeviceN extends PDColorSp
array.set( DEVICEN_ATTRIBUTES, attributes.getCOSDictionary() );
}
}
-
+
/**
* Returns the components of the color in the alternate colorspace for the given tint value.
* @param tintValues a list containing the tint values
@@ -269,32 +267,9 @@ public class PDDeviceN extends PDColorSp
public COSArray calculateColorValues(List<COSBase> tintValues) throws IOException
{
PDFunction tintTransform = getTintTransform();
- if(tintTransform instanceof PDFunctionType4)
- {
- LOG.warn("Unsupported tint transformation type: "+tintTransform.getClass().getName()
- + " in "+getClass().getName()+".getColorValues()"
- + " using color black instead.");
- int numberOfComponents = getAlternateColorSpace().getNumberOfComponents();
- // To get black as color:
- // 0 is used for the single value(s) if the colorspace is gray or RGB based
- COSArray retval = new COSArray();
- for ( int i=0; i < numberOfComponents; i++ )
- {
- retval.add(COSInteger.ZERO);
- }
- // 1 is used as forth value if the colorspace is CMYK based
- if (numberOfComponents == PDDeviceCMYK.INSTANCE.getNumberOfComponents())
- {
- retval.set(3, COSInteger.ONE);
- }
- return retval;
- }
- else
- {
- COSArray tint = new COSArray();
- tint.addAll(tintValues);
- return tintTransform.eval(tint);
- }
+ COSArray tint = new COSArray();
+ tint.addAll(tintValues);
+ return tintTransform.eval(tint);
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDSeparation.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDSeparation.java?rev=1185719&r1=1185718&r2=1185719&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDSeparation.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDSeparation.java Tue Oct 18 15:23:56 2011
@@ -25,10 +25,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.common.function.PDFunction;
-import org.apache.pdfbox.pdmodel.common.function.PDFunctionType4;
/**
* This class represents a Separation color space.
@@ -205,37 +203,18 @@ public class PDSeparation extends PDColo
{
array.set( 3, tint );
}
-
+
/**
* Returns the components of the color in the alternate colorspace for the given tint value.
+ * @param tintValue the tint value
* @return COSArray with the color components
* @throws IOException If the tint function is not supported
*/
public COSArray calculateColorValues(COSBase tintValue) throws IOException
{
PDFunction tintTransform = getTintTransform();
- if(tintTransform instanceof PDFunctionType4)
- {
- log.warn("Unsupported tint transformation type: "+tintTransform.getClass().getName()
- + " in "+getClass().getName()+".getColorValues()"
- + " using color black instead.");
- int numberOfComponents = getAlternateColorSpace().getNumberOfComponents();
- // To get black as color:
- // 0.0f is used for the single value(s) if the colorspace is gray or RGB based
- // 1.0f is used for the single value if the colorspace is CMYK based
- float colorValue = numberOfComponents == 4 ? 1.0f : 0.0f;
- COSArray retval = new COSArray();
- for (int i=0;i<numberOfComponents;i++)
- {
- retval.add(new COSFloat(colorValue));
- }
- return retval;
- }
- else
- {
- COSArray tint = new COSArray();
- tint.add(tintValue);
- return tintTransform.eval(tint);
- }
+ COSArray tint = new COSArray();
+ tint.add(tintValue);
+ return tintTransform.eval(tint);
}
}
Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestAll.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestAll.java?rev=1185719&r1=1185718&r2=1185719&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestAll.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/TestAll.java Tue Oct 18 15:23:56 2011
@@ -86,6 +86,7 @@ public class TestAll extends TestCase
suite.addTestSuite( org.apache.pdfbox.pdmodel.graphics.optionalcontent.TestOptionalContentGroups.class );
suite.addTestSuite( org.apache.pdfbox.util.TestLayerUtility.class );
suite.addTestSuite( org.apache.pdfbox.TestTextToPdf.class );
+ suite.addTest( org.apache.pdfbox.pdmodel.common.function.TestFunctions.suite() );
suite.addTestSuite( TestIOUtils.class );
suite.addTestSuite( TestPackedBitArray.class );
Added: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java (added)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+import org.apache.pdfbox.pdmodel.common.function.type4.TestOperators;
+import org.apache.pdfbox.pdmodel.common.function.type4.TestParser;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests PDF functions.
+ *
+ * @version $Revision$
+ */
+public class TestFunctions extends TestCase
+{
+
+ /**
+ * The main method to run tests.
+ *
+ * @param args The command line arguments.
+ */
+ public static void main( String[] args )
+ {
+ String[] arg = {TestFunctions.class.getName()};
+ junit.textui.TestRunner.main( arg );
+ }
+
+ /**
+ * This will get the suite of test that this class holds.
+ *
+ * @return All of the tests that this class holds.
+ */
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite(TestFunctions.class.getName());
+ suite.addTestSuite(TestOperators.class);
+ suite.addTestSuite(TestParser.class);
+ suite.addTestSuite(TestPDFunctionType4.class);
+ return suite;
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestFunctions.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java?rev=1185719&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java (added)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java Tue Oct 18 15:23:56 2011
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.io.RandomAccessBuffer;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the {@link PDFunctionType4} class.
+ *
+ * @version $Revision$
+ */
+public class TestPDFunctionType4 extends TestCase
+{
+
+ private PDFunctionType4 createFunction(String function, float[] domain, float[] range)
+ throws IOException
+ {
+ COSDictionary dict = new COSDictionary();
+ dict.setInt("FunctionType", 4);
+ COSArray domainArray = new COSArray();
+ domainArray.setFloatArray(domain);
+ dict.setItem("Domain", domainArray);
+ COSArray rangeArray = new COSArray();
+ rangeArray.setFloatArray(range);
+ dict.setItem("Range", rangeArray);
+
+ COSStream functionStream = new COSStream(dict, new RandomAccessBuffer());
+ OutputStream out = functionStream.createUnfilteredStream();
+ byte[] data = function.getBytes("US-ASCII");
+ out.write(data, 0, data.length);
+ out.flush();
+
+ return new PDFunctionType4(functionStream);
+ }
+
+ /**
+ * Checks the {@link PDFunctionType4}.
+ * @throws Exception if an error occurs
+ */
+ public void testFunctionSimple() throws Exception
+ {
+ String functionText = "{ add }";
+ //Simply adds the two arguments and returns the result
+
+ PDFunctionType4 function = createFunction(functionText,
+ new float[] {-1.0f, 1.0f, -1.0f, 1.0f},
+ new float[] {-1.0f, 1.0f});
+
+ COSArray input = new COSArray();
+ input.setFloatArray(new float[] {0.8f, 0.1f});
+ COSArray output = function.eval(input);
+
+ assertEquals(1, output.size());
+ assertEquals(0.9f, ((COSFloat)output.get(0)).floatValue(), 0.0001f);
+
+ input = new COSArray();
+ input.setFloatArray(new float[] {0.8f, 0.3f}); //results in 1.1f being outside Range
+ output = function.eval(input);
+
+ assertEquals(1, output.size());
+ assertEquals(new COSFloat(1.0f), output.get(0));
+
+ input = new COSArray();
+ input.setFloatArray(new float[] {0.8f, 1.2f}); //input argument outside Dimension
+ output = function.eval(input);
+
+ assertEquals(1, output.size());
+ assertEquals(new COSFloat(1.0f), output.get(0));
+ }
+
+ /**
+ * Checks the handling of the argument order for a {@link PDFunctionType4}.
+ * @throws Exception if an error occurs
+ */
+ public void testFunctionArgumentOrder() throws Exception
+ {
+ String functionText = "{ pop }";
+ //pops the top-most argument and returns the second as is.
+
+ PDFunctionType4 function = createFunction(functionText,
+ new float[] {-1.0f, 1.0f, -1.0f, 1.0f},
+ new float[] {-1.0f, 1.0f});
+
+ COSArray input = new COSArray();
+ input.setFloatArray(new float[] {-0.7f, 0.0f});
+ COSArray output = function.eval(input);
+
+ assertEquals(1, output.size());
+ assertEquals(0.0f, ((COSFloat)output.get(0)).floatValue(), 0.0001f);
+ //TODO not sure if this is really correct
+ }
+
+}
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/common/function/TestPDFunctionType4.java
------------------------------------------------------------------------------
svn:keywords = Id