aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/pdfbox/pdmodel/interactive
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/pdfbox/pdmodel/interactive')
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDActionFactory.java96
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDAdditionalActions.java106
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDAnnotationAdditionalActions.java380
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDDocumentCatalogAdditionalActions.java238
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDFormFieldAdditionalActions.java216
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/PDPageAdditionalActions.java150
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDAction.java187
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionGoTo.java92
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionJavaScript.java102
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionLaunch.java244
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionRemoteGoTo.java187
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionURI.java183
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDWindowsLaunchParams.java180
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/action/type/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotation.java503
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationRubberStamp.java153
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationUnknown.java54
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java65
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceDictionary.java245
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceStream.java146
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/annotation/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/PDSignature.java85
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDDestination.java125
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDNamedDestination.java142
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageDestination.java155
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitDestination.java102
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitHeightDestination.java132
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitRectangleDestination.java188
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitWidthDestination.java134
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageXYZDestination.java159
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java62
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java425
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java320
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDAcroForm.java328
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDAppearance.java645
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDCheckbox.java187
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceButton.java95
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceField.java127
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDField.java610
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDFieldFactory.java218
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDPushButton.java84
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDRadioCollection.java170
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDSignature.java90
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDTextbox.java64
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDUnknownField.java72
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/PDVariableText.java324
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/form/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThread.java152
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThreadBead.java234
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/package.html9
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/PDViewerPreferences.java365
-rw-r--r--src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/package.html9
57 files changed, 9411 insertions, 0 deletions
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDActionFactory.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDActionFactory.java
new file mode 100644
index 0000000..bf0c156
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDActionFactory.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionGoTo;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionJavaScript;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionLaunch;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionRemoteGoTo;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionURI;
+
+/**
+ * This class will take a dictionary and determine which type of action to create.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.4 $
+ */
+public class PDActionFactory
+{
+ /**
+ * Utility Class.
+ */
+ private PDActionFactory()
+ {
+ //utility class
+ }
+
+ /**
+ * This will create the correct type of action based on the type specified
+ * in the dictionary.
+ *
+ * @param action An action dictionary.
+ *
+ * @return An action of the correct type.
+ */
+ public static PDAction createAction( COSDictionary action )
+ {
+ PDAction retval = null;
+ if( action != null )
+ {
+ String type = action.getNameAsString( "S" );
+ if( PDActionJavaScript.SUB_TYPE.equals( type ) )
+ {
+ retval = new PDActionJavaScript( action );
+ }
+ else if( PDActionGoTo.SUB_TYPE.equals( type ) )
+ {
+ retval = new PDActionGoTo( action );
+ }
+ else if( PDActionLaunch.SUB_TYPE.equals( type ) )
+ {
+ retval = new PDActionLaunch( action );
+ }
+ else if( PDActionRemoteGoTo.SUB_TYPE.equals( type ) )
+ {
+ retval = new PDActionRemoteGoTo( action );
+ }
+ else if( PDActionURI.SUB_TYPE.equals( type ) )
+ {
+ retval = new PDActionURI( action );
+ }
+ }
+ return retval;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAdditionalActions.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAdditionalActions.java
new file mode 100644
index 0000000..fc2f79b
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAdditionalActions.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+
+/**
+ * This represents a dictionary of actions that occur due to events.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDAdditionalActions implements COSObjectable
+{
+ private COSDictionary actions;
+
+ /**
+ * Default constructor.
+ */
+ public PDAdditionalActions()
+ {
+ actions = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDAdditionalActions( COSDictionary a )
+ {
+ actions = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return actions;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return actions;
+ }
+
+ /**
+ * Get the F action.
+ *
+ * @return The F action.
+ */
+ public PDAction getF()
+ {
+ return PDActionFactory.createAction( (COSDictionary)actions.getDictionaryObject("F" ) );
+ }
+
+ /**
+ * Set the F action.
+ *
+ * @param action Get the F action.
+ */
+ public void setF( PDAction action )
+ {
+ actions.setItem( "F", action );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAnnotationAdditionalActions.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAnnotationAdditionalActions.java
new file mode 100644
index 0000000..9b9232e
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDAnnotationAdditionalActions.java
@@ -0,0 +1,380 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+
+/**
+ * This class represents an annotation's dictionary of actions
+ * that occur due to events.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public class PDAnnotationAdditionalActions implements COSObjectable
+{
+ private COSDictionary actions;
+
+ /**
+ * Default constructor.
+ */
+ public PDAnnotationAdditionalActions()
+ {
+ actions = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDAnnotationAdditionalActions( COSDictionary a )
+ {
+ actions = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return actions;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return actions;
+ }
+
+ /**
+ * This will get an action to be performed when the cursor
+ * enters the annotation's active area.
+ *
+ * @return The E entry of annotation's additional actions dictionary.
+ */
+ public PDAction getE()
+ {
+ COSDictionary e = (COSDictionary)actions.getDictionaryObject( "E" );
+ PDAction retval = null;
+ if( e != null )
+ {
+ retval = PDActionFactory.createAction( e );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the cursor
+ * enters the annotation's active area.
+ *
+ * @param e The action to be performed.
+ */
+ public void setE( PDAction e )
+ {
+ actions.setItem( "E", e );
+ }
+
+ /**
+ * This will get an action to be performed when the cursor
+ * exits the annotation's active area.
+ *
+ * @return The X entry of annotation's additional actions dictionary.
+ */
+ public PDAction getX()
+ {
+ COSDictionary x = (COSDictionary)actions.getDictionaryObject( "X" );
+ PDAction retval = null;
+ if( x != null )
+ {
+ retval = PDActionFactory.createAction( x );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the cursor
+ * exits the annotation's active area.
+ *
+ * @param x The action to be performed.
+ */
+ public void setX( PDAction x )
+ {
+ actions.setItem( "X", x );
+ }
+
+ /**
+ * This will get an action to be performed when the mouse button
+ * is pressed inside the annotation's active area.
+ * The name D stands for "down".
+ *
+ * @return The d entry of annotation's additional actions dictionary.
+ */
+ public PDAction getD()
+ {
+ COSDictionary d = (COSDictionary)actions.getDictionaryObject( "D" );
+ PDAction retval = null;
+ if( d != null )
+ {
+ retval = PDActionFactory.createAction( d );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the mouse button
+ * is pressed inside the annotation's active area.
+ * The name D stands for "down".
+ *
+ * @param d The action to be performed.
+ */
+ public void setD( PDAction d )
+ {
+ actions.setItem( "D", d );
+ }
+
+ /**
+ * This will get an action to be performed when the mouse button
+ * is released inside the annotation's active area.
+ * The name U stands for "up".
+ *
+ * @return The U entry of annotation's additional actions dictionary.
+ */
+ public PDAction getU()
+ {
+ COSDictionary u = (COSDictionary)actions.getDictionaryObject( "U" );
+ PDAction retval = null;
+ if( u != null )
+ {
+ retval = PDActionFactory.createAction( u );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the mouse button
+ * is released inside the annotation's active area.
+ * The name U stands for "up".
+ *
+ * @param u The action to be performed.
+ */
+ public void setU( PDAction u )
+ {
+ actions.setItem( "U", u );
+ }
+
+ /**
+ * This will get an action to be performed when the annotation
+ * receives the input focus.
+ *
+ * @return The Fo entry of annotation's additional actions dictionary.
+ */
+ public PDAction getFo()
+ {
+ COSDictionary fo = (COSDictionary)actions.getDictionaryObject( "Fo" );
+ PDAction retval = null;
+ if( fo != null )
+ {
+ retval = PDActionFactory.createAction( fo );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the annotation
+ * receives the input focus.
+ *
+ * @param fo The action to be performed.
+ */
+ public void setFo( PDAction fo )
+ {
+ actions.setItem( "Fo", fo );
+ }
+
+ /**
+ * This will get an action to be performed when the annotation
+ * loses the input focus.
+ * The name Bl stands for "blurred".
+ *
+ * @return The Bl entry of annotation's additional actions dictionary.
+ */
+ public PDAction getBl()
+ {
+ COSDictionary bl = (COSDictionary)actions.getDictionaryObject( "Bl" );
+ PDAction retval = null;
+ if( bl != null )
+ {
+ retval = PDActionFactory.createAction( bl );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the annotation
+ * loses the input focus.
+ * The name Bl stands for "blurred".
+ *
+ * @param bl The action to be performed.
+ */
+ public void setBl( PDAction bl )
+ {
+ actions.setItem( "Bl", bl );
+ }
+
+ /**
+ * This will get an action to be performed when the page containing
+ * the annotation is opened. The action is executed after the O action
+ * in the page's additional actions dictionary and the OpenAction entry
+ * in the document catalog, if such actions are present.
+ *
+ * @return The PO entry of annotation's additional actions dictionary.
+ */
+ public PDAction getPO()
+ {
+ COSDictionary po = (COSDictionary)actions.getDictionaryObject( "PO" );
+ PDAction retval = null;
+ if( po != null )
+ {
+ retval = PDActionFactory.createAction( po );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page containing
+ * the annotation is opened. The action is executed after the O action
+ * in the page's additional actions dictionary and the OpenAction entry
+ * in the document catalog, if such actions are present.
+ *
+ * @param po The action to be performed.
+ */
+ public void setPO( PDAction po )
+ {
+ actions.setItem( "PO", po );
+ }
+
+ /**
+ * This will get an action to be performed when the page containing
+ * the annotation is closed. The action is executed before the C action
+ * in the page's additional actions dictionary, if present.
+ *
+ * @return The PC entry of annotation's additional actions dictionary.
+ */
+ public PDAction getPC()
+ {
+ COSDictionary pc = (COSDictionary)actions.getDictionaryObject( "PC" );
+ PDAction retval = null;
+ if( pc != null )
+ {
+ retval = PDActionFactory.createAction( pc );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page containing
+ * the annotation is closed. The action is executed before the C action
+ * in the page's additional actions dictionary, if present.
+ *
+ * @param pc The action to be performed.
+ */
+ public void setPC( PDAction pc )
+ {
+ actions.setItem( "PC", pc );
+ }
+
+ /**
+ * This will get an action to be performed when the page containing
+ * the annotation becomes visible in the viewer application's user interface.
+ *
+ * @return The PV entry of annotation's additional actions dictionary.
+ */
+ public PDAction getPV()
+ {
+ COSDictionary pv = (COSDictionary)actions.getDictionaryObject( "PV" );
+ PDAction retval = null;
+ if( pv != null )
+ {
+ retval = PDActionFactory.createAction( pv );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page containing
+ * the annotation becomes visible in the viewer application's user interface.
+ *
+ * @param pv The action to be performed.
+ */
+ public void setPV( PDAction pv )
+ {
+ actions.setItem( "PV", pv );
+ }
+
+ /**
+ * This will get an action to be performed when the page containing the annotation
+ * is no longer visible in the viewer application's user interface.
+ *
+ * @return The PI entry of annotation's additional actions dictionary.
+ */
+ public PDAction getPI()
+ {
+ COSDictionary pi = (COSDictionary)actions.getDictionaryObject( "PI" );
+ PDAction retval = null;
+ if( pi != null )
+ {
+ retval = PDActionFactory.createAction( pi );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page containing the annotation
+ * is no longer visible in the viewer application's user interface.
+ *
+ * @param pi The action to be performed.
+ */
+ public void setPI( PDAction pi )
+ {
+ actions.setItem( "PI", pi );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDDocumentCatalogAdditionalActions.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDDocumentCatalogAdditionalActions.java
new file mode 100644
index 0000000..6164de1
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDDocumentCatalogAdditionalActions.java
@@ -0,0 +1,238 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+
+/**
+ * This class represents a document catalog's dictionary of actions
+ * that occur due to events.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public class PDDocumentCatalogAdditionalActions implements COSObjectable
+{
+ private COSDictionary actions;
+
+ /**
+ * Default constructor.
+ */
+ public PDDocumentCatalogAdditionalActions()
+ {
+ actions = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDDocumentCatalogAdditionalActions( COSDictionary a )
+ {
+ actions = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return actions;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return actions;
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * before closing a document.
+ * The name WC stands for "will close".
+ *
+ * @return The WC entry of document catalog's additional actions dictionary.
+ */
+ public PDAction getWC()
+ {
+ COSDictionary wc = (COSDictionary)actions.getDictionaryObject( "WC" );
+ PDAction retval = null;
+ if( wc != null )
+ {
+ retval = PDActionFactory.createAction( wc );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * before closing a document.
+ * The name WC stands for "will close".
+ *
+ * @param wc The action to be performed.
+ */
+ public void setWC( PDAction wc )
+ {
+ actions.setItem( "WC", wc );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * before saving a document.
+ * The name WS stands for "will save".
+ *
+ * @return The WS entry of document catalog's additional actions dictionary.
+ */
+ public PDAction getWS()
+ {
+ COSDictionary ws = (COSDictionary)actions.getDictionaryObject( "WS" );
+ PDAction retval = null;
+ if( ws != null )
+ {
+ retval = PDActionFactory.createAction( ws );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * before saving a document.
+ * The name WS stands for "will save".
+ *
+ * @param ws The action to be performed.
+ */
+ public void setWS( PDAction ws )
+ {
+ actions.setItem( "WS", ws );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * after saving a document.
+ * The name DS stands for "did save".
+ *
+ * @return The DS entry of document catalog's additional actions dictionary.
+ */
+ public PDAction getDS()
+ {
+ COSDictionary ds = (COSDictionary)actions.getDictionaryObject( "DS" );
+ PDAction retval = null;
+ if( ds != null )
+ {
+ retval = PDActionFactory.createAction( ds );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * after saving a document.
+ * The name DS stands for "did save".
+ *
+ * @param ds The action to be performed.
+ */
+ public void setDS( PDAction ds )
+ {
+ actions.setItem( "DS", ds );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * before printing a document.
+ * The name WP stands for "will print".
+ *
+ * @return The WP entry of document catalog's additional actions dictionary.
+ */
+ public PDAction getWP()
+ {
+ COSDictionary wp = (COSDictionary)actions.getDictionaryObject( "WP" );
+ PDAction retval = null;
+ if( wp != null )
+ {
+ retval = PDActionFactory.createAction( wp );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * before printing a document.
+ * The name WP stands for "will print".
+ *
+ * @param wp The action to be performed.
+ */
+ public void setWP( PDAction wp )
+ {
+ actions.setItem( "WP", wp );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * after printing a document.
+ * The name DP stands for "did print".
+ *
+ * @return The DP entry of document catalog's additional actions dictionary.
+ */
+ public PDAction getDP()
+ {
+ COSDictionary dp = (COSDictionary)actions.getDictionaryObject( "DP" );
+ PDAction retval = null;
+ if( dp != null )
+ {
+ retval = PDActionFactory.createAction( dp );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * after printing a document.
+ * The name DP stands for "did print".
+ *
+ * @param dp The action to be performed.
+ */
+ public void setDP( PDAction dp )
+ {
+ actions.setItem( "DP", dp );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDFormFieldAdditionalActions.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDFormFieldAdditionalActions.java
new file mode 100644
index 0000000..2a594f3
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDFormFieldAdditionalActions.java
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+
+/**
+ * This class represents a form field's dictionary of actions
+ * that occur due to events.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public class PDFormFieldAdditionalActions implements COSObjectable
+{
+ private COSDictionary actions;
+
+ /**
+ * Default constructor.
+ */
+ public PDFormFieldAdditionalActions()
+ {
+ actions = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDFormFieldAdditionalActions( COSDictionary a )
+ {
+ actions = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return actions;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return actions;
+ }
+
+ /**
+ * This will get a JavaScript action to be performed when the user
+ * types a keystroke into a text field or combo box or modifies the
+ * selection in a scrollable list box. This allows the keystroke to
+ * be checked for validity and rejected or modified.
+ *
+ * @return The K entry of form field's additional actions dictionary.
+ */
+ public PDAction getK()
+ {
+ COSDictionary k = (COSDictionary)actions.getDictionaryObject( "K" );
+ PDAction retval = null;
+ if( k != null )
+ {
+ retval = PDActionFactory.createAction( k );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed when the user
+ * types a keystroke into a text field or combo box or modifies the
+ * selection in a scrollable list box. This allows the keystroke to
+ * be checked for validity and rejected or modified.
+ *
+ * @param k The action to be performed.
+ */
+ public void setK( PDAction k )
+ {
+ actions.setItem( "K", k );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed before
+ * the field is formatted to display its current value. This
+ * allows the field's value to be modified before formatting.
+ *
+ * @return The F entry of form field's additional actions dictionary.
+ */
+ public PDAction getF()
+ {
+ COSDictionary f = (COSDictionary)actions.getDictionaryObject( "F" );
+ PDAction retval = null;
+ if( f != null )
+ {
+ retval = PDActionFactory.createAction( f );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed before
+ * the field is formatted to display its current value. This
+ * allows the field's value to be modified before formatting.
+ *
+ * @param f The action to be performed.
+ */
+ public void setF( PDAction f )
+ {
+ actions.setItem( "F", f );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed
+ * when the field's value is changed. This allows the
+ * new value to be checked for validity.
+ * The name V stands for "validate".
+ *
+ * @return The V entry of form field's additional actions dictionary.
+ */
+ public PDAction getV()
+ {
+ COSDictionary v = (COSDictionary)actions.getDictionaryObject( "V" );
+ PDAction retval = null;
+ if( v != null )
+ {
+ retval = PDActionFactory.createAction( v );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed
+ * when the field's value is changed. This allows the
+ * new value to be checked for validity.
+ * The name V stands for "validate".
+ *
+ * @param v The action to be performed.
+ */
+ public void setV( PDAction v )
+ {
+ actions.setItem( "V", v );
+ }
+
+ /**
+ * This will get a JavaScript action to be performed in order to recalculate
+ * the value of this field when that of another field changes. The order in which
+ * the document's fields are recalculated is defined by the CO entry in the
+ * interactive form dictionary.
+ * The name C stands for "calculate".
+ *
+ * @return The C entry of form field's additional actions dictionary.
+ */
+ public PDAction getC()
+ {
+ COSDictionary c = (COSDictionary)actions.getDictionaryObject( "C" );
+ PDAction retval = null;
+ if( c != null )
+ {
+ retval = PDActionFactory.createAction( c );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a JavaScript action to be performed in order to recalculate
+ * the value of this field when that of another field changes. The order in which
+ * the document's fields are recalculated is defined by the CO entry in the
+ * interactive form dictionary.
+ * The name C stands for "calculate".
+ *
+ * @param c The action to be performed.
+ */
+ public void setC( PDAction c )
+ {
+ actions.setItem( "C", c );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/PDPageAdditionalActions.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDPageAdditionalActions.java
new file mode 100644
index 0000000..f15ffa7
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/PDPageAdditionalActions.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+
+/**
+ * This class represents a page object's dictionary of actions
+ * that occur due to events.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageAdditionalActions implements COSObjectable
+{
+ private COSDictionary actions;
+
+ /**
+ * Default constructor.
+ */
+ public PDPageAdditionalActions()
+ {
+ actions = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDPageAdditionalActions( COSDictionary a )
+ {
+ actions = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return actions;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return actions;
+ }
+
+ /**
+ * This will get an action to be performed when the page
+ * is opened. This action is independent of any that may be
+ * defined by the OpenAction entry in the document catalog,
+ * and is executed after such an action.
+ *
+ * @return The O entry of page object's additional actions dictionary.
+ */
+ public PDAction getO()
+ {
+ COSDictionary o = (COSDictionary)actions.getDictionaryObject( "O" );
+ PDAction retval = null;
+ if( o != null )
+ {
+ retval = PDActionFactory.createAction( o );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page
+ * is opened. This action is independent of any that may be
+ * defined by the OpenAction entry in the document catalog,
+ * and is executed after such an action.
+ *
+ * @param o The action to be performed.
+ */
+ public void setO( PDAction o )
+ {
+ actions.setItem( "O", o );
+ }
+
+ /**
+ * This will get an action to be performed when the page
+ * is closed. This action applies to the page being closed,
+ * and is executed before any other page opened.
+ *
+ * @return The C entry of page object's additional actions dictionary.
+ */
+ public PDAction getC()
+ {
+ COSDictionary c = (COSDictionary)actions.getDictionaryObject( "C" );
+ PDAction retval = null;
+ if( c != null )
+ {
+ retval = PDActionFactory.createAction( c );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set an action to be performed when the page
+ * is closed. This action applies to the page being closed,
+ * and is executed before any other page opened.
+ *
+ * @param c The action to be performed.
+ */
+ public void setC( PDAction c )
+ {
+ actions.setItem( "C", c );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/action/package.html
new file mode 100644
index 0000000..63cbfc0
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package represents actions that can be performed in a PDF document.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDAction.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDAction.java
new file mode 100644
index 0000000..21d40fc
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDAction.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.common.COSArrayList;
+import org.pdfbox.pdmodel.interactive.action.PDActionFactory;
+
+/**
+ * This represents an action that can be executed in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public abstract class PDAction implements COSObjectable
+{
+ /**
+ * The type of PDF object.
+ */
+ public static final String TYPE = "Action";
+
+ /**
+ * The action dictionary.
+ */
+ protected COSDictionary action;
+
+ /**
+ * Default constructor.
+ */
+ public PDAction()
+ {
+ action = new COSDictionary();
+ setType( TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDAction( COSDictionary a )
+ {
+ action = a;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return action;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return action;
+ }
+
+ /**
+ * This will get the type of PDF object that the actions dictionary describes.
+ * If present must be Action for an action dictionary.
+ *
+ * @return The Type of PDF object.
+ */
+ public String getType()
+ {
+ return action.getNameAsString( "Type" );
+ }
+
+ /**
+ * This will set the type of PDF object that the actions dictionary describes.
+ * If present must be Action for an action dictionary.
+ *
+ * @param type The new Type for the PDF object.
+ */
+ public void setType( String type )
+ {
+ action.setName( "Type", type );
+ }
+
+ /**
+ * This will get the type of action that the actions dictionary describes.
+ * If present, must be Action for an action dictionary.
+ *
+ * @return The S entry of actions dictionary.
+ */
+ public String getSubType()
+ {
+ return action.getNameAsString( "S" );
+ }
+
+ /**
+ * This will set the type of action that the actions dictionary describes.
+ * If present, must be Action for an action dictionary.
+ *
+ * @param s The new type of action.
+ */
+ public void setSubType( String s )
+ {
+ action.setName( "S", s );
+ }
+
+ /**
+ * This will get the next action, or sequence of actions, to be performed after this one.
+ * The value is either a single action dictionary or an array of action dictionaries
+ * to be performed in order.
+ *
+ * @return The Next action or sequence of actions.
+ */
+ public List getNext()
+ {
+ List retval = null;
+ COSBase next = action.getDictionaryObject( "Next" );
+ if( next instanceof COSDictionary )
+ {
+ PDAction pdAction = PDActionFactory.createAction( (COSDictionary) next );
+ retval = new COSArrayList(pdAction, next, action, "Next" );
+ }
+ else if( next instanceof COSArray )
+ {
+ COSArray array = (COSArray)next;
+ List actions = new ArrayList();
+ for( int i=0; i<array.size(); i++ )
+ {
+ actions.add( PDActionFactory.createAction( (COSDictionary) array.getObject( i )));
+ }
+ retval = new COSArrayList( actions, array );
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set the next action, or sequence of actions, to be performed after this one.
+ * The value is either a single action dictionary or an array of action dictionaries
+ * to be performed in order.
+ *
+ * @param next The Next action or sequence of actions.
+ */
+ public void setNext( List next )
+ {
+ action.setItem( "Next", COSArrayList.converterToCOSArray( next ) );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionGoTo.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionGoTo.java
new file mode 100644
index 0000000..abf0ab5
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionGoTo.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
+
+/**
+ * This represents a go-to action that can be executed in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.1 $
+ */
+public class PDActionGoTo extends PDAction
+{
+ /**
+ * This type of action this object represents.
+ */
+ public static final String SUB_TYPE = "GoTo";
+
+ /**
+ * Default constructor.
+ */
+ public PDActionGoTo()
+ {
+ super();
+ setSubType( SUB_TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDActionGoTo( COSDictionary a )
+ {
+ super( a );
+ }
+
+ /**
+ * This will get the destination to jump to.
+ *
+ * @return The D entry of the specific go-to action dictionary.
+ *
+ * @throws IOException If there is an error creating the destination.
+ */
+ public PDDestination getDestination() throws IOException
+ {
+ return PDDestination.create( getCOSDictionary().getDictionaryObject( "D" ) );
+ }
+
+ /**
+ * This will set the destination to jump to.
+ *
+ * @param d The destination.
+ */
+ public void setDestination( PDDestination d )
+ {
+ getCOSDictionary().setItem( "D", d );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionJavaScript.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionJavaScript.java
new file mode 100644
index 0000000..3148dd3
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionJavaScript.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.pdmodel.common.PDTextStream;
+
+/**
+ * This represents a JavaScript action.
+ *
+ * @author Michael Schwarzenberger (mi2kee@gmail.com)
+ * @version $Revision: 1.1 $
+ */
+public class PDActionJavaScript extends PDAction
+{
+ /**
+ * This type of action this object represents.
+ */
+ public static final String SUB_TYPE = "JavaScript";
+
+ /**
+ * Constructor #1.
+ */
+ public PDActionJavaScript()
+ {
+ super();
+ setSubType( SUB_TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param js Some javascript code.
+ */
+ public PDActionJavaScript( String js )
+ {
+ this();
+ setAction( js );
+ }
+
+ /**
+ * Constructor #2.
+ *
+ * @param a The action dictionary.
+ */
+ public PDActionJavaScript(COSDictionary a)
+ {
+ super(a);
+ }
+
+ /**
+ * @param sAction The JavaScript.
+ */
+ public void setAction(PDTextStream sAction)
+ {
+ action.setItem("JS", sAction);
+ }
+
+ /**
+ * @param sAction The JavaScript.
+ */
+ public void setAction(String sAction)
+ {
+ action.setString("JS", sAction);
+ }
+
+ /**
+ * @return The Javascript Code.
+ */
+ public PDTextStream getAction()
+ {
+ return PDTextStream.createTextStream( action.getDictionaryObject("JS") );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionLaunch.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionLaunch.java
new file mode 100644
index 0000000..3c2ef74
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionLaunch.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2004-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.filespecification.PDFileSpecification;
+
+/**
+ * This represents a launch action that can be executed in a PDF document.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.3 $
+ */
+public class PDActionLaunch extends PDAction
+{
+
+ /**
+ * This type of action this object represents.
+ */
+ public static final String SUB_TYPE = "Launch";
+
+ /**
+ * Default constructor.
+ */
+ public PDActionLaunch()
+ {
+ super();
+ setSubType( SUB_TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDActionLaunch( COSDictionary a )
+ {
+ super( a );
+ }
+
+ /**
+ * This will get the application to be launched or the document
+ * to be opened or printed. It is required if none of the entries
+ * Win, Mac or Unix is present. If this entry is absent and the
+ * viewer application does not understand any of the alternative
+ * entries it should do nothing.
+ *
+ * @return The F entry of the specific launch action dictionary.
+ */
+ public PDFileSpecification getFile()
+ {
+ return PDFileSpecification.createFS( getCOSDictionary().getDictionaryObject( "F" ) );
+ }
+
+ /**
+ * This will set the application to be launched or the document
+ * to be opened or printed. It is required if none of the entries
+ * Win, Mac or Unix is present. If this entry is absent and the
+ * viewer application does not understand any of the alternative
+ * entries it should do nothing.
+ *
+ * @param fs The file specification.
+ */
+ public void setFile( PDFileSpecification fs )
+ {
+ getCOSDictionary().setItem( "F", fs );
+ }
+
+ /**
+ * This will get a dictionary containing Windows-specific launch parameters.
+ *
+ * @return The Win entry of of the specific launch action dictionary.
+ */
+ public PDWindowsLaunchParams getWinLaunchParams()
+ {
+ COSDictionary win = (COSDictionary)action.getDictionaryObject( "Win" );
+ PDWindowsLaunchParams retval = null;
+ if( win != null )
+ {
+ retval = new PDWindowsLaunchParams( win );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set a dictionary containing Windows-specific launch parameters.
+ *
+ * @param win The action to be performed.
+ */
+ public void setWinLaunchParams( PDWindowsLaunchParams win )
+ {
+ action.setItem( "Win", win );
+ }
+
+ /**
+ * This will get the file name to be launched or the document to be opened
+ * or printed, in standard Windows pathname format. If the name string includes
+ * a backslash character (\), the backslash must itself be preceded by a backslash.
+ * This value must be a single string; it is not a file specification.
+ *
+ * @return The F entry of the specific Windows launch parameter dictionary.
+ */
+ public String getF()
+ {
+ return action.getString( "F" );
+ }
+
+ /**
+ * This will set the file name to be launched or the document to be opened
+ * or printed, in standard Windows pathname format. If the name string includes
+ * a backslash character (\), the backslash must itself be preceded by a backslash.
+ * This value must be a single string; it is not a file specification.
+ *
+ * @param f The file name to be launched.
+ */
+ public void setF( String f )
+ {
+ action.setString( "F", f );
+ }
+
+ /**
+ * This will get the string specifying the default directory in standard DOS syntax.
+ *
+ * @return The D entry of the specific Windows launch parameter dictionary.
+ */
+ public String getD()
+ {
+ return action.getString( "D" );
+ }
+
+ /**
+ * This will set the string specifying the default directory in standard DOS syntax.
+ *
+ * @param d The default directory.
+ */
+ public void setD( String d )
+ {
+ action.setString( "D", d );
+ }
+
+ /**
+ * This will get the string specifying the operation to perform:
+ * open to open a document
+ * print to print a document
+ * If the F entry designates an application instead of a document, this entry
+ * is ignored and the application is launched. Default value: open.
+ *
+ * @return The O entry of the specific Windows launch parameter dictionary.
+ */
+ public String getO()
+ {
+ return action.getString( "O" );
+ }
+
+ /**
+ * This will set the string specifying the operation to perform:
+ * open to open a document
+ * print to print a document
+ * If the F entry designates an application instead of a document, this entry
+ * is ignored and the application is launched. Default value: open.
+ *
+ * @param o The operation to perform.
+ */
+ public void setO( String o )
+ {
+ action.setString( "O", o );
+ }
+
+ /**
+ * This will get a parameter string to be passed to the application designated by the F entry.
+ * This entry should be omitted if F designates a document.
+ *
+ * @return The P entry of the specific Windows launch parameter dictionary.
+ */
+ public String getP()
+ {
+ return action.getString( "P" );
+ }
+
+ /**
+ * This will set a parameter string to be passed to the application designated by the F entry.
+ * This entry should be omitted if F designates a document.
+ *
+ * @param p The parameter string.
+ */
+ public void setP( String p )
+ {
+ action.setString( "P", p );
+ }
+
+ /**
+ * This will specify whether to open the destination document in a new window.
+ * If this flag is false, the destination document will replace the current
+ * document in the same window. If this entry is absent, the viewer application
+ * should behave in accordance with the current user preference. This entry is
+ * ignored if the file designated by the F entry is not a PDF document.
+ *
+ * @return A flag specifying whether to open the destination document in a new window.
+ */
+ public boolean shouldOpenInNewWindow()
+ {
+ return action.getBoolean( "NewWindow", true );
+ }
+
+ /**
+ * This will specify the destination document to open in a new window.
+ *
+ * @param value The flag value.
+ */
+ public void setOpenInNewWindow( boolean value )
+ {
+ action.setBoolean( "NewWindow", value );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionRemoteGoTo.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionRemoteGoTo.java
new file mode 100644
index 0000000..73dbc6c
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionRemoteGoTo.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.filespecification.PDFileSpecification;
+
+/**
+ * This represents a remote go-to action that can be executed in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.2 $
+ */
+public class PDActionRemoteGoTo extends PDAction
+{
+ /**
+ * This type of action this object represents.
+ */
+ public static final String SUB_TYPE = "GoToR";
+
+ /**
+ * Default constructor.
+ */
+ public PDActionRemoteGoTo()
+ {
+ action = new COSDictionary();
+ setSubType( SUB_TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDActionRemoteGoTo( COSDictionary a )
+ {
+ super( a );
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return action;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return action;
+ }
+
+ /**
+ * This will get the type of action that the actions dictionary describes.
+ * It must be GoToR for a remote go-to action.
+ *
+ * @return The S entry of the specific remote go-to action dictionary.
+ */
+ public String getS()
+ {
+ return action.getNameAsString( "S" );
+ }
+
+ /**
+ * This will set the type of action that the actions dictionary describes.
+ * It must be GoToR for a remote go-to action.
+ *
+ * @param s The remote go-to action.
+ */
+ public void setS( String s )
+ {
+ action.setName( "S", s );
+ }
+
+ /**
+ * This will get the file in which the destination is located.
+ *
+ * @return The F entry of the specific remote go-to action dictionary.
+ */
+ public PDFileSpecification getFile()
+ {
+ return PDFileSpecification.createFS( action.getDictionaryObject( "F" ) );
+ }
+
+ /**
+ * This will set the file in which the destination is located.
+ *
+ * @param fs The file specification.
+ */
+ public void setFile( PDFileSpecification fs )
+ {
+ action.setItem( "F", fs );
+ }
+
+ /**
+ * This will get the destination to jump to.
+ * If the value is an array defining an explicit destination,
+ * its first element must be a page number within the remote
+ * document rather than an indirect reference to a page object
+ * in the current document. The first page is numbered 0.
+ *
+ * @return The D entry of the specific remote go-to action dictionary.
+ */
+
+ // Array or String.
+ public COSBase getD()
+ {
+ return action.getDictionaryObject( "D" );
+ }
+
+ /**
+ * This will set the destination to jump to.
+ * If the value is an array defining an explicit destination,
+ * its first element must be a page number within the remote
+ * document rather than an indirect reference to a page object
+ * in the current document. The first page is numbered 0.
+ *
+ * @param d The destination.
+ */
+
+ // In case the value is an array.
+ public void setD( COSBase d )
+ {
+ action.setItem( "D", d );
+ }
+
+ /**
+ * This will specify whether to open the destination document in a new window.
+ * If this flag is false, the destination document will replace the current
+ * document in the same window. If this entry is absent, the viewer application
+ * should behave in accordance with the current user preference.
+ *
+ * @return A flag specifying whether to open the destination document in a new window.
+ */
+ public boolean shouldOpenInNewWindow()
+ {
+ return action.getBoolean( "NewWindow", true );
+ }
+
+ /**
+ * This will specify the destination document to open in a new window.
+ *
+ * @param value The flag value.
+ */
+ public void setOpenInNewWindow( boolean value )
+ {
+ action.setBoolean( "NewWindow", value );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionURI.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionURI.java
new file mode 100644
index 0000000..b98495d
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDActionURI.java
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+/**
+ * This represents a URI action that can be executed in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @author Panagiotis Toumasis (ptoumasis@mail.gr)
+ * @version $Revision: 1.2 $
+ */
+public class PDActionURI extends PDAction
+{
+ /**
+ * This type of action this object represents.
+ */
+ public static final String SUB_TYPE = "URI";
+
+ /**
+ * Default constructor.
+ */
+ public PDActionURI()
+ {
+ action = new COSDictionary();
+ setSubType( SUB_TYPE );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a The action dictionary.
+ */
+ public PDActionURI( COSDictionary a )
+ {
+ super( a );
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return action;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return action;
+ }
+
+ /**
+ * This will get the type of action that the actions dictionary describes.
+ * It must be URI for a URI action.
+ *
+ * @return The S entry of the specific URI action dictionary.
+ */
+ public String getS()
+ {
+ return action.getNameAsString( "S" );
+ }
+
+ /**
+ * This will set the type of action that the actions dictionary describes.
+ * It must be URI for a URI action.
+ *
+ * @param s The URI action.
+ */
+ public void setS( String s )
+ {
+ action.setName( "S", s );
+ }
+
+ /**
+ * This will get the uniform resource identifier to resolve, encoded in 7-bit ASCII.
+ *
+ * @return The URI entry of the specific URI action dictionary.
+ */
+ public String getURI()
+ {
+ return action.getString( "URI" );
+ }
+
+ /**
+ * This will set the uniform resource identifier to resolve, encoded in 7-bit ASCII.
+ *
+ * @param uri The uniform resource identifier.
+ */
+ public void setURI( String uri )
+ {
+ action.setString( "URI", uri );
+ }
+
+ /**
+ * This will specify whether to track the mouse position when the URI is resolved.
+ * Default value: false.
+ * This entry applies only to actions triggered by the user's clicking an annotation;
+ * it is ignored for actions associated with outline items or with a document's OpenAction entry.
+ *
+ * @return A flag specifying whether to track the mouse position when the URI is resolved.
+ */
+ public boolean shouldTrackMousePosition()
+ {
+ return action.getBoolean( "MousePosition", true );
+ }
+
+ /**
+ * This will specify whether to track the mouse position when the URI is resolved.
+ *
+ * @param value The flag value.
+ */
+ public void setTrackMousePosition( boolean value )
+ {
+ action.setBoolean( "MousePosition", value );
+ }
+
+ /**
+ * This will get the base URI to be used in resolving relative URI references.
+ * URI actions within the document may specify URIs in partial form, to be interpreted
+ * relative to this base address. If no base URI is specified, such partial URIs
+ * will be interpreted relative to the location of the document itself.
+ * The use of this entry is parallel to that of the body element &lt;BASE&gt;, as described
+ * in the HTML 4.01 Specification.
+ *
+ * @return The URI entry of the specific URI dictionary.
+ */
+ public String getBase()
+ {
+ return action.getString( "Base" );
+ }
+
+ /**
+ * This will set the base URI to be used in resolving relative URI references.
+ * URI actions within the document may specify URIs in partial form, to be interpreted
+ * relative to this base address. If no base URI is specified, such partial URIs
+ * will be interpreted relative to the location of the document itself.
+ * The use of this entry is parallel to that of the body element &lt;BASE&gt;, as described
+ * in the HTML 4.01 Specification.
+ *
+ * @param base The the base URI to be used.
+ */
+ public void setBase( String base )
+ {
+ action.setString( "Base", base );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDWindowsLaunchParams.java b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDWindowsLaunchParams.java
new file mode 100644
index 0000000..7af4ff2
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/PDWindowsLaunchParams.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.action.type;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * Launch paramaters for the windows OS.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDWindowsLaunchParams implements COSObjectable
+{
+ /**
+ * The open operation for the launch.
+ */
+ public static final String OPERATION_OPEN = "open";
+ /**
+ * The print operation for the lanuch.
+ */
+ public static final String OPERATION_PRINT = "print";
+
+ /**
+ * The params dictionary.
+ */
+ protected COSDictionary params;
+
+ /**
+ * Default constructor.
+ */
+ public PDWindowsLaunchParams()
+ {
+ params = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param p The params dictionary.
+ */
+ public PDWindowsLaunchParams( COSDictionary p )
+ {
+ params = p;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return params;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return params;
+ }
+
+ /**
+ * The file to launch.
+ *
+ * @return The executable/document to launch.
+ */
+ public String getFilename()
+ {
+ return params.getString( "F" );
+ }
+
+ /**
+ * Set the file to launch.
+ *
+ * @param file The executable/document to launch.
+ */
+ public void setFilename( String file )
+ {
+ params.setString( "F", file );
+ }
+
+ /**
+ * The dir to launch from.
+ *
+ * @return The dir of the executable/document to launch.
+ */
+ public String getDirectory()
+ {
+ return params.getString( "D" );
+ }
+
+ /**
+ * Set the dir to launch from.
+ *
+ * @param dir The dir of the executable/document to launch.
+ */
+ public void setDirectory( String dir )
+ {
+ params.setString( "D", dir );
+ }
+
+ /**
+ * Get the operation to perform on the file. This method will not return null,
+ * OPERATION_OPEN is the default.
+ *
+ * @return The operation to perform for the file.
+ * @see PDWindowsLaunchParams#OPERATION_OPEN
+ * @see PDWindowsLaunchParams#OPERATION_PRINT
+ */
+ public String getOperation()
+ {
+ return params.getString( "O", OPERATION_OPEN );
+ }
+
+ /**
+ * Set the operation to perform..
+ *
+ * @param op The operation to perform on the file.
+ */
+ public void setOperation( String op )
+ {
+ params.setString( "D", op );
+ }
+
+ /**
+ * A parameter to pass the executable.
+ *
+ * @return The parameter to pass the executable.
+ */
+ public String getExecuteParam()
+ {
+ return params.getString( "P" );
+ }
+
+ /**
+ * Set the parameter to pass the executable.
+ *
+ * @param param The parameter for the executable.
+ */
+ public void setExecuteParam( String param )
+ {
+ params.setString( "P", param );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/action/type/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/package.html
new file mode 100644
index 0000000..f0db5c3
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/action/type/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package contains all of the available PDF action types.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotation.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotation.java
new file mode 100644
index 0000000..4d245c0
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotation.java
@@ -0,0 +1,503 @@
+/**
+ * Copyright (c) 2003-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.common.PDRectangle;
+import org.pdfbox.pdmodel.interactive.action.PDAdditionalActions;
+import org.pdfbox.util.BitFlagHelper;
+import org.pdfbox.cos.COSBase;
+
+/**
+ * This class represents a PDF annotation.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.10 $
+ */
+public abstract class PDAnnotation implements COSObjectable
+{
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_INVISIBLE = 1 << 0;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_HIDDEN = 1 << 1;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_PRINTED = 1 << 2;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_NO_ZOOM = 1 << 3;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_NO_ROTATE = 1 << 4;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_NO_VIEW = 1 << 5;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_READ_ONLY = 1 << 6;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_LOCKED = 1 << 7;
+ /**
+ * An annotation flag.
+ */
+ public static final int FLAG_TOGGLE_NO_VIEW = 1 << 8;
+
+
+
+ private COSDictionary dictionary;
+
+ /**
+ * Create the correct annotation from the base COS object.
+ *
+ * @param base The COS object that is the annotation.
+ * @return The correctly typed annotation object.
+ * @throws IOException If there is an error while creating the annotation.
+ */
+ public static PDAnnotation createAnnotation( COSBase base ) throws IOException
+ {
+ PDAnnotation annot = null;
+ if( base instanceof COSDictionary )
+ {
+ COSDictionary annotDic = (COSDictionary)base;
+ String subtype = annotDic.getString( COSName.SUBTYPE );
+ if( subtype.equals( PDAnnotationRubberStamp.SUB_TYPE ) )
+ {
+ annot = new PDAnnotationRubberStamp(annotDic);
+ }
+ else
+ {
+ annot = new PDAnnotationUnknown( annotDic );
+ }
+ }
+ else
+ {
+ throw new IOException( "Error: Unknown annotation type " + base );
+ }
+
+ return annot;
+ }
+
+ /**
+ * Constructor.
+ */
+ public PDAnnotation()
+ {
+ dictionary = new COSDictionary();
+ dictionary.setItem( COSName.TYPE, COSName.getPDFName( "Annot" ) );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dict The annotations dictionary.
+ */
+ public PDAnnotation( COSDictionary dict )
+ {
+ dictionary = dict;
+ }
+
+ /**
+ * returns the dictionary.
+ * @return the dictionary
+ */
+ public COSDictionary getDictionary()
+ {
+ return dictionary;
+ }
+
+ /**
+ * The annotation rectangle, defining the location of the annotation
+ * on the page in default user space units. This is usually required and should
+ * not return null on valid PDF documents. But where this is a parent form field
+ * with children, such as radio button collections then the rectangle will be null.
+ *
+ * @return The Rect value of this annotation.
+ */
+ public PDRectangle getRectangle()
+ {
+ COSArray rectArray = (COSArray)dictionary.getDictionaryObject( COSName.getPDFName( "Rect" ) );
+ PDRectangle rectangle = null;
+ if( rectArray != null )
+ {
+ rectangle = new PDRectangle( rectArray );
+ }
+ return rectangle;
+ }
+
+ /**
+ * This will set the rectangle for this annotation.
+ *
+ * @param rectangle The new rectangle values.
+ */
+ public void setRectangle( PDRectangle rectangle )
+ {
+ dictionary.setItem( COSName.getPDFName( "Rect" ), rectangle.getCOSArray() );
+ }
+
+ /**
+ * This will get the flags for this field.
+ *
+ * @return flags The set of flags.
+ */
+ public int getAnnotationFlags()
+ {
+ return getDictionary().getInt( "F", 0 );
+ }
+
+ /**
+ * This will set the flags for this field.
+ *
+ * @param flags The new flags.
+ */
+ public void setAnnotationFlags( int flags )
+ {
+ getDictionary().setInt( "F", flags );
+ }
+
+ /**
+ * Interface method for COSObjectable.
+ *
+ * @return This object as a standard COS object.
+ */
+ public COSBase getCOSObject()
+ {
+ return getDictionary();
+ }
+
+ /**
+ * This will get the name of the current appearance stream if any.
+ *
+ * @return The name of the appearance stream.
+ */
+ public String getAppearanceStream()
+ {
+ String retval = null;
+ COSName name = (COSName)getDictionary().getDictionaryObject( COSName.getPDFName( "AS" ) );
+ if( name != null )
+ {
+ retval = name.getName();
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the annotations appearance stream name.
+ *
+ * @param as The name of the appearance stream.
+ */
+ public void setAppearanceStream( String as )
+ {
+ if( as == null )
+ {
+ getDictionary().removeItem( COSName.getPDFName( "AS" ) );
+ }
+ else
+ {
+ getDictionary().setItem( COSName.getPDFName( "AS" ), COSName.getPDFName( as ) );
+ }
+ }
+
+ /**
+ * This will get the appearance dictionary associated with this annotation.
+ * This may return null.
+ *
+ * @return This annotations appearance.
+ */
+ public PDAppearanceDictionary getAppearance()
+ {
+ PDAppearanceDictionary ap = null;
+ COSDictionary apDic = (COSDictionary)dictionary.getDictionaryObject( COSName.getPDFName( "AP" ) );
+ if( apDic != null )
+ {
+ ap = new PDAppearanceDictionary( apDic );
+ }
+ return ap;
+ }
+
+ /**
+ * This will set the appearance associated with this annotation.
+ *
+ * @param appearance The appearance dictionary for this annotation.
+ */
+ public void setAppearance( PDAppearanceDictionary appearance )
+ {
+ COSDictionary ap = null;
+ if( appearance != null )
+ {
+ ap = appearance.getDictionary();
+ }
+ dictionary.setItem( COSName.getPDFName( "AP" ), ap );
+ }
+
+ /**
+ * Get the invisible flag.
+ *
+ * @return The invisible flag.
+ */
+ public boolean isInvisible()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_INVISIBLE );
+ }
+
+ /**
+ * Set the invisible flag.
+ *
+ * @param invisible The new invisible flag.
+ */
+ public void setInvisible( boolean invisible )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_INVISIBLE, invisible );
+ }
+
+ /**
+ * Get the hidden flag.
+ *
+ * @return The hidden flag.
+ */
+ public boolean isHidden()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_HIDDEN );
+ }
+
+ /**
+ * Set the hidden flag.
+ *
+ * @param hidden The new hidden flag.
+ */
+ public void setHidden( boolean hidden )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_HIDDEN, hidden );
+ }
+
+ /**
+ * Get the printed flag.
+ *
+ * @return The printed flag.
+ */
+ public boolean isPrinted()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_PRINTED );
+ }
+
+ /**
+ * Set the printed flag.
+ *
+ * @param printed The new printed flag.
+ */
+ public void setPrinted( boolean printed )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_PRINTED, printed );
+ }
+
+ /**
+ * Get the noZoom flag.
+ *
+ * @return The noZoom flag.
+ */
+ public boolean isNoZoom()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_NO_ZOOM );
+ }
+
+ /**
+ * Set the noZoom flag.
+ *
+ * @param noZoom The new noZoom flag.
+ */
+ public void setNoZoom( boolean noZoom )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_NO_ZOOM, noZoom );
+ }
+
+ /**
+ * Get the noRotate flag.
+ *
+ * @return The noRotate flag.
+ */
+ public boolean isNoRotate()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_NO_ROTATE );
+ }
+
+ /**
+ * Set the noRotate flag.
+ *
+ * @param noRotate The new noRotate flag.
+ */
+ public void setNoRotate( boolean noRotate )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_NO_ROTATE, noRotate );
+ }
+
+ /**
+ * Get the noView flag.
+ *
+ * @return The noView flag.
+ */
+ public boolean isNoView()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_NO_VIEW );
+ }
+
+ /**
+ * Set the noView flag.
+ *
+ * @param noView The new noView flag.
+ */
+ public void setNoView( boolean noView )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_NO_VIEW, noView );
+ }
+
+ /**
+ * Get the readOnly flag.
+ *
+ * @return The readOnly flag.
+ */
+ public boolean isReadOnly()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_READ_ONLY );
+ }
+
+ /**
+ * Set the readOnly flag.
+ *
+ * @param readOnly The new readOnly flag.
+ */
+ public void setReadOnly( boolean readOnly )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_READ_ONLY, readOnly );
+ }
+
+ /**
+ * Get the locked flag.
+ *
+ * @return The locked flag.
+ */
+ public boolean isLocked()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_LOCKED );
+ }
+
+ /**
+ * Set the locked flag.
+ *
+ * @param locked The new locked flag.
+ */
+ public void setLocked( boolean locked )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_LOCKED, locked );
+ }
+
+ /**
+ * Get the toggleNoView flag.
+ *
+ * @return The toggleNoView flag.
+ */
+ public boolean isToggleNoView()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "F", FLAG_TOGGLE_NO_VIEW );
+ }
+
+ /**
+ * Set the toggleNoView flag.
+ *
+ * @param toggleNoView The new toggleNoView flag.
+ */
+ public void setToggleNoView( boolean toggleNoView )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "F", FLAG_TOGGLE_NO_VIEW, toggleNoView );
+ }
+
+ /**
+ * Get the additional actions for this field. This will return null
+ * if there are no additional actions for this field.
+ *
+ * @return The actions of the field.
+ */
+ public PDAdditionalActions getActions()
+ {
+ COSDictionary aa = (COSDictionary)dictionary.getDictionaryObject( "AA" );
+ PDAdditionalActions retval = null;
+ if( aa != null )
+ {
+ retval = new PDAdditionalActions( aa );
+ }
+ return retval;
+ }
+
+ /**
+ * Set the actions of the field.
+ *
+ * @param actions The field actions.
+ */
+ public void setActions( PDAdditionalActions actions )
+ {
+ dictionary.setItem( "AA", actions );
+ }
+
+ /**
+ * Get the "contents" of the field.
+ *
+ * @return the value of the contents
+ */
+ public String getContents()
+ {
+ return dictionary.getString(COSName.CONTENTS);
+ }
+
+ /**
+ * Set the "contents" of the field.
+ *
+ * @param value the value of the contents.
+ */
+ public void setContents( String value)
+ {
+ dictionary.setString(COSName.CONTENTS, value);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationRubberStamp.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationRubberStamp.java
new file mode 100644
index 0000000..089b19f
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationRubberStamp.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+/**
+ * This is the class that represents a widget.
+ *
+ * @author Paul King
+ * @version $Revision: 1.1 $
+ */
+public class PDAnnotationRubberStamp extends PDAnnotation
+{
+
+ /*
+ * The various values of the rubber stamp as defined in
+ * the PDF 1.6 reference Table 8.28
+ */
+
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_APPROVED = "Approved";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_EXPERIMENTAL = "Experimental";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_NOT_APPROVED = "NotApproved";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_AS_IS = "AsIs";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_EXPIRED = "Expired";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_NOT_FOR_PUBLIC_RELEASE = "NotForPublicRelease";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_FOR_PUBLIC_RELEASE = "ForPublicRelease";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_DRAFT = "Draft";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_FOR_COMMENT = "ForComment";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_TOP_SECRET = "TopSecret";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_DEPARTMENTAL = "Departmental";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_CONFIDENTIAL = "Confidential";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_FINAL = "Final";
+ /**
+ * Constant for the name of a rubber stamp.
+ */
+ public static final String NAME_SOLD = "Sold";
+
+ /**
+ * The type of annotation.
+ */
+ public static final String SUB_TYPE = "Stamp";
+
+ /**
+ * Constructor.
+ */
+ public PDAnnotationRubberStamp()
+ {
+ super();
+ getDictionary().setItem( COSName.SUBTYPE, COSName.getPDFName( SUB_TYPE ) );
+ }
+
+ /**
+ * Creates a Rubber Stamp annotation from a COSDictionary, expected to be
+ * a correct object definition.
+ *
+ * @param field the PDF objet to represent as a field.
+ */
+ public PDAnnotationRubberStamp(COSDictionary field)
+ {
+ super( field );
+ }
+
+ /**
+ * This will set the name (and hence appearance, AP taking precedence)
+ * For this annotation. See the NAME_XXX constants for valid values.
+ *
+ * @param name The name of the rubber stamp.
+ */
+ public void setName( String name )
+ {
+ getDictionary().setName(COSName.NAME, name);
+ }
+
+ /**
+ * This will retrieve the name (and hence appearance, AP taking precedence)
+ * For this annotation. The default is DRAFT.
+ *
+ * @return The name of this rubber stamp, see the NAME_XXX constants.
+ */
+ public String getName()
+ {
+ return getDictionary().getNameAsString(COSName.NAME, NAME_DRAFT);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationUnknown.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationUnknown.java
new file mode 100644
index 0000000..408f5fb
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationUnknown.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import org.pdfbox.cos.COSDictionary;
+
+/**
+ * This is the class that represents an arbitary Unknown Annotation type.
+ *
+ * @author Paul King
+ * @version $Revision: 1.1 $
+ */
+public class PDAnnotationUnknown extends PDAnnotation
+{
+
+ /**
+ * Creates an arbitary annotation from a COSDictionary, expected to be
+ * a correct object definition for some sort of annotation.
+ *
+ * @param dic The dictionary which represents this Annotation.
+ */
+ public PDAnnotationUnknown(COSDictionary dic)
+ {
+ super( dic );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java
new file mode 100644
index 0000000..5faf983
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+/**
+ * This is the class that represents a widget.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDAnnotationWidget extends PDAnnotation
+{
+
+ /**
+ * Constructor.
+ */
+ public PDAnnotationWidget()
+ {
+ super();
+ getDictionary().setItem( COSName.SUBTYPE, COSName.getPDFName( "Widget" ) );
+ }
+
+
+ /**
+ * Creates a PDWidget from a COSDictionary, expected to be
+ * a correct object definition for a field in PDF.
+ *
+ * @param field the PDF objet to represent as a field.
+ */
+ public PDAnnotationWidget(COSDictionary field)
+ {
+ super( field );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceDictionary.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceDictionary.java
new file mode 100644
index 0000000..da3a182
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceDictionary.java
@@ -0,0 +1,245 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSStream;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.common.COSDictionaryMap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This class represents a PDF /AP entry the appearance dictionary.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDAppearanceDictionary implements COSObjectable
+{
+ private COSDictionary dictionary;
+
+ /**
+ * Constructor.
+ */
+ public PDAppearanceDictionary()
+ {
+ dictionary = new COSDictionary();
+ //the N entry is required.
+ dictionary.setItem( COSName.getPDFName( "N" ), new COSDictionary() );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dict The annotations dictionary.
+ */
+ public PDAppearanceDictionary( COSDictionary dict )
+ {
+ dictionary = dict;
+ }
+
+ /**
+ * returns the dictionary.
+ * @return the dictionary
+ */
+ public COSDictionary getDictionary()
+ {
+ return dictionary;
+ }
+
+ /**
+ * returns the dictionary.
+ * @return the dictionary
+ */
+ public COSBase getCOSObject()
+ {
+ return dictionary;
+ }
+
+ /**
+ * This will return a list of appearances. In the case where there is
+ * only one appearance the map will contain one entry whose key is the string
+ * "default".
+ *
+ * @return A list of key(java.lang.String) value(PDAppearanceStream) pairs
+ */
+ public Map getNormalAppearance()
+ {
+ COSBase ap = dictionary.getDictionaryObject( COSName.getPDFName( "N" ) );
+ if( ap instanceof COSStream )
+ {
+ COSStream aux = (COSStream) ap;
+ ap = new COSDictionary();
+ ((COSDictionary)ap).setItem(COSName.getPDFName( "default" ), aux );
+ }
+ COSDictionary map = (COSDictionary)ap;
+ Map actuals = new HashMap();
+ Map retval = new COSDictionaryMap( actuals, map );
+ Iterator asNames = map.keyList().iterator();
+ while( asNames.hasNext() )
+ {
+ COSName asName = (COSName)asNames.next();
+ COSStream as = (COSStream)map.getDictionaryObject( asName );
+ actuals.put( asName.getName(), new PDAppearanceStream( as ) );
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set a list of appearances. If you would like to set the single
+ * appearance then you should use the key "default", and when the PDF is written
+ * back to the filesystem then there will only be one stream.
+ *
+ * @param appearanceMap The updated map with the appearance.
+ */
+ public void setNormalAppearance( Map appearanceMap )
+ {
+ dictionary.setItem( COSName.getPDFName( "N" ), COSDictionaryMap.convert( appearanceMap ) );
+ }
+
+ /**
+ * This will set the normal appearance when there is only one appearance
+ * to be shown.
+ *
+ * @param ap The appearance stream to show.
+ */
+ public void setNormalAppearance( PDAppearanceStream ap )
+ {
+ dictionary.setItem( COSName.getPDFName( "N" ), ap.getStream() );
+ }
+
+ /**
+ * This will return a list of appearances. In the case where there is
+ * only one appearance the map will contain one entry whose key is the string
+ * "default". If there is no rollover appearance then the normal appearance
+ * will be returned. Which means that this method will never return null.
+ *
+ * @return A list of key(java.lang.String) value(PDAppearanceStream) pairs
+ */
+ public Map getRolloverAppearance()
+ {
+ Map retval = null;
+ COSBase ap = dictionary.getDictionaryObject( COSName.getPDFName( "R" ) );
+ if( ap == null )
+ {
+ retval = getNormalAppearance();
+ }
+ else
+ {
+ if( ap instanceof COSStream )
+ {
+ ap = new COSDictionary();
+ ((COSDictionary)ap).setItem(COSName.getPDFName( "default" ), ap );
+ }
+ COSDictionary map = (COSDictionary)ap;
+ Map actuals = new HashMap();
+ retval = new COSDictionaryMap( actuals, map );
+ Iterator asNames = map.keyList().iterator();
+ while( asNames.hasNext() )
+ {
+ COSName asName = (COSName)asNames.next();
+ COSStream as = (COSStream)map.getDictionaryObject( asName );
+ actuals.put( asName.getName(), new PDAppearanceStream( as ) );
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set a list of appearances. If you would like to set the single
+ * appearance then you should use the key "default", and when the PDF is written
+ * back to the filesystem then there will only be one stream.
+ *
+ * @param appearanceMap The updated map with the appearance.
+ */
+ public void setRolloverAppearance( Map appearanceMap )
+ {
+ dictionary.setItem( COSName.getPDFName( "R" ), COSDictionaryMap.convert( appearanceMap ) );
+ }
+
+ /**
+ * This will return a list of appearances. In the case where there is
+ * only one appearance the map will contain one entry whose key is the string
+ * "default". If there is no rollover appearance then the normal appearance
+ * will be returned. Which means that this method will never return null.
+ *
+ * @return A list of key(java.lang.String) value(PDAppearanceStream) pairs
+ */
+ public Map getDownAppearance()
+ {
+ Map retval = null;
+ COSBase ap = dictionary.getDictionaryObject( COSName.getPDFName( "D" ) );
+ if( ap == null )
+ {
+ retval = getNormalAppearance();
+ }
+ else
+ {
+ if( ap instanceof COSStream )
+ {
+ ap = new COSDictionary();
+ ((COSDictionary)ap).setItem(COSName.getPDFName( "default" ), ap );
+ }
+ COSDictionary map = (COSDictionary)ap;
+ Map actuals = new HashMap();
+ retval = new COSDictionaryMap( actuals, map );
+ Iterator asNames = map.keyList().iterator();
+ while( asNames.hasNext() )
+ {
+ COSName asName = (COSName)asNames.next();
+ COSStream as = (COSStream)map.getDictionaryObject( asName );
+ actuals.put( asName.getName(), new PDAppearanceStream( as ) );
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set a list of appearances. If you would like to set the single
+ * appearance then you should use the key "default", and when the PDF is written
+ * back to the filesystem then there will only be one stream.
+ *
+ * @param appearanceMap The updated map with the appearance.
+ */
+ public void setDownAppearance( Map appearanceMap )
+ {
+ dictionary.setItem( COSName.getPDFName( "D" ), COSDictionaryMap.convert( appearanceMap ) );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceStream.java b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceStream.java
new file mode 100644
index 0000000..ca3f4a4
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/PDAppearanceStream.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.annotation;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSStream;
+
+import org.pdfbox.pdmodel.common.PDRectangle;
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+import org.pdfbox.pdmodel.PDResources;
+
+
+/**
+ * This class represents an appearance for an annotation.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDAppearanceStream implements COSObjectable
+{
+ private COSStream stream = null;
+
+
+ /**
+ * Constructor.
+ *
+ * @param s The cos stream for this appearance.
+ */
+ public PDAppearanceStream( COSStream s )
+ {
+ stream = s;
+ }
+
+ /**
+ * This will return the underlying stream.
+ *
+ * @return The wrapped stream.
+ */
+ public COSStream getStream()
+ {
+ return stream;
+ }
+
+ /**
+ * @see COSObjectable#getCOSObject()
+ */
+ public COSBase getCOSObject()
+ {
+ return stream;
+ }
+
+ /**
+ * Get the bounding box for this appearance. This may return null in which
+ * case the Rectangle from the annotation should be used.
+ *
+ * @return The bounding box for this appearance.
+ */
+ public PDRectangle getBoundingBox()
+ {
+ PDRectangle box = null;
+ COSArray bbox = (COSArray)stream.getDictionaryObject( COSName.getPDFName( "BBox" ) );
+ if( bbox != null )
+ {
+ box = new PDRectangle( bbox );
+ }
+ return box;
+ }
+
+ /**
+ * This will set the bounding box for this appearance stream.
+ *
+ * @param rectangle The new bounding box.
+ */
+ public void setBoundingBox( PDRectangle rectangle )
+ {
+ COSArray array = null;
+ if( rectangle != null )
+ {
+ array = rectangle.getCOSArray();
+ }
+ stream.setItem( COSName.getPDFName( "BBox" ), array );
+ }
+
+ /**
+ * This will get the resources for this appearance stream.
+ *
+ * @return The appearance stream resources.
+ */
+ public PDResources getResources()
+ {
+ PDResources retval = null;
+ COSDictionary dict = (COSDictionary)stream.getDictionaryObject( COSName.RESOURCES );
+ if( dict != null )
+ {
+ retval = new PDResources( dict );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the new resources.
+ *
+ * @param resources The new resources.
+ */
+ public void setResources( PDResources resources )
+ {
+ COSDictionary dict = null;
+ if( resources != null )
+ {
+ dict = resources.getCOSDictionary();
+ }
+ stream.setItem( COSName.RESOURCES, dict );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/annotation/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/package.html
new file mode 100644
index 0000000..4d9fdeb
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/annotation/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The annotation package contains classes that work with PDF annotation elements.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/PDSignature.java b/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/PDSignature.java
new file mode 100644
index 0000000..7ef1c1e
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/PDSignature.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.digitalsignature;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * This represents a digital signature that can be attached to a document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDSignature implements COSObjectable
+{
+ private COSDictionary sig;
+
+ /**
+ * Default constructor.
+ */
+ public PDSignature()
+ {
+ sig = new COSDictionary();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param s The signature dictionary.
+ */
+ public PDSignature( COSDictionary s )
+ {
+ sig = s;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return sig;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return sig;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/package.html
new file mode 100644
index 0000000..d9944e6
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/digitalsignature/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The digitial signature library will manage signatures that are stored in the PDF document.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDDestination.java
new file mode 100644
index 0000000..98a0345
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDDestination.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2004-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * This represents a destination in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.4 $
+ */
+public abstract class PDDestination implements COSObjectable
+{
+
+ /**
+ * This will create a new destination depending on the type of COSBase
+ * that is passed in.
+ *
+ * @param base The base level object.
+ *
+ * @return A new destination.
+ *
+ * @throws IOException If the base cannot be converted to a Destination.
+ */
+ public static PDDestination create( COSBase base ) throws IOException
+ {
+ PDDestination retval = null;
+ if( base == null )
+ {
+ //this is ok, just return null.
+ }
+ else if( base instanceof COSArray && ((COSArray)base).size() > 0 )
+ {
+ COSArray array = (COSArray)base;
+ COSName type = (COSName)array.getObject( 1 );
+ String typeString = type.getName();
+ if( typeString.equals( PDPageFitDestination.TYPE ) ||
+ typeString.equals( PDPageFitDestination.TYPE_BOUNDED ))
+ {
+ retval = new PDPageFitDestination( array );
+ }
+ else if( typeString.equals( PDPageFitHeightDestination.TYPE ) ||
+ typeString.equals( PDPageFitHeightDestination.TYPE_BOUNDED ))
+ {
+ retval = new PDPageFitHeightDestination( array );
+ }
+ else if( typeString.equals( PDPageFitRectangleDestination.TYPE ) )
+ {
+ retval = new PDPageFitRectangleDestination( array );
+ }
+ else if( typeString.equals( PDPageFitWidthDestination.TYPE ) ||
+ typeString.equals( PDPageFitWidthDestination.TYPE_BOUNDED ))
+ {
+ retval = new PDPageFitWidthDestination( array );
+ }
+ else if( typeString.equals( PDPageXYZDestination.TYPE ) )
+ {
+ retval = new PDPageXYZDestination( array );
+ }
+ else
+ {
+ throw new IOException( "Unknown destination type:" + type );
+ }
+ }
+ else if( base instanceof COSString )
+ {
+ retval = new PDNamedDestination( (COSString)base );
+ }
+ else if( base instanceof COSName )
+ {
+ retval = new PDNamedDestination( (COSName)base );
+ }
+ else
+ {
+ throw new IOException( "Error: can't convert to Destination " + base );
+ }
+ return retval;
+ }
+
+ /**
+ * Return a string representation of this class.
+ *
+ * @return A human readable string.
+ */
+ public String toString()
+ {
+ return super.toString();
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDNamedDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDNamedDestination.java
new file mode 100644
index 0000000..11da8e7
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDNamedDestination.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+
+/**
+ * This represents a destination to a page by referencing it with a name.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.2 $
+ */
+public class PDNamedDestination extends PDDestination
+{
+ private COSBase namedDestination;
+
+ /**
+ * Constructor.
+ *
+ * @param dest The named destination.
+ */
+ public PDNamedDestination( COSString dest )
+ {
+ namedDestination = dest;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dest The named destination.
+ */
+ public PDNamedDestination( COSName dest )
+ {
+ namedDestination = dest;
+ }
+
+ /**
+ * Default constructor.
+ */
+ public PDNamedDestination()
+ {
+ //default, so do nothing
+ }
+
+ /**
+ * Default constructor.
+ *
+ * @param dest The named destination.
+ */
+ public PDNamedDestination( String dest )
+ {
+ namedDestination = new COSString( dest );
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return namedDestination;
+ }
+
+ /**
+ * This will get the name of the destination.
+ *
+ * @return The name of the destination.
+ */
+ public String getNamedDestination()
+ {
+ String retval = null;
+ if( namedDestination instanceof COSString )
+ {
+ retval = ((COSString)namedDestination).getString();
+ }
+ else if( namedDestination instanceof COSName )
+ {
+ retval = ((COSName)namedDestination).getName();
+ }
+
+ return retval;
+ }
+
+ /**
+ * Set the named destination.
+ *
+ * @param dest The new named destination.
+ *
+ * @throws IOException If there is an error setting the named destination.
+ */
+ public void setNamedDestination( String dest ) throws IOException
+ {
+ if( namedDestination instanceof COSString )
+ {
+ COSString string = ((COSString)namedDestination);
+ string.reset();
+ string.append( dest.getBytes() );
+ }
+ else if( dest == null )
+ {
+ namedDestination = null;
+ }
+ else
+ {
+ namedDestination = new COSString( dest );
+ }
+ }
+
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageDestination.java
new file mode 100644
index 0000000..74dbf9a
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageDestination.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSNumber;
+
+import org.pdfbox.pdmodel.PDPage;
+
+/**
+ * This represents a destination to a page, see subclasses for specific parameters.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public abstract class PDPageDestination extends PDDestination
+{
+ /**
+ * Storage for the page destination.
+ */
+ protected COSArray array;
+
+ /**
+ * Constructor to create empty page destination.
+ *
+ */
+ protected PDPageDestination()
+ {
+ array = new COSArray();
+ }
+
+ /**
+ * Constructor to create empty page destination.
+ *
+ * @param arr A page destination array.
+ */
+ protected PDPageDestination( COSArray arr )
+ {
+ array = arr;
+ }
+
+ /**
+ * This will get the page for this destination. A page destination
+ * can either reference a page or a page number(when doing a remote destination to
+ * another PDF). If this object is referencing by page number then this method will
+ * return null and getPageNumber should be used.
+ *
+ * @return The page for this destination.
+ */
+ public PDPage getPage()
+ {
+ PDPage retval = null;
+ if( array.size() > 0 )
+ {
+ COSBase page = array.getObject( 0 );
+ if( page instanceof COSDictionary )
+ {
+ retval = new PDPage( (COSDictionary)page );
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * Set the page for this destination.
+ *
+ * @param page The page for the destination.
+ */
+ public void setPage( PDPage page )
+ {
+ array.set( 0, page );
+ }
+
+ /**
+ * This will get the page number for this destination. A page destination
+ * can either reference a page or a page number(when doing a remote destination to
+ * another PDF). If this object is referencing by page number then this method will
+ * return that number, otherwise -1 will be returned.
+ *
+ * @return The page number for this destination.
+ */
+ public int getPageNumber()
+ {
+ int retval = -1;
+ if( array.size() > 0 )
+ {
+ COSBase page = array.getObject( 0 );
+ if( page instanceof COSNumber )
+ {
+ retval = ((COSNumber)page).intValue();
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * Set the page number for this destination.
+ *
+ * @param pageNumber The page for the destination.
+ */
+ public void setPageNumber( int pageNumber )
+ {
+ array.set( 0, pageNumber );
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return array;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSArray getCOSArray()
+ {
+ return array;
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitDestination.java
new file mode 100644
index 0000000..8f46bbe
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitDestination.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+
+/**
+ * This represents a destination to a page and the page contents will be magnified to just
+ * fit on the screen.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageFitDestination extends PDPageDestination
+{
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE = "Fit";
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE_BOUNDED = "FitB";
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDPageFitDestination()
+ {
+ super();
+ array.growToSize(2);
+ array.setName( 1, TYPE );
+
+ }
+
+ /**
+ * Constructor from an existing destination array.
+ *
+ * @param arr The destination array.
+ */
+ public PDPageFitDestination( COSArray arr )
+ {
+ super( arr );
+ }
+
+ /**
+ * A flag indicating if this page destination should just fit bounding box of the PDF.
+ *
+ * @return true If the destination should fit just the bounding box.
+ */
+ public boolean fitBoundingBox()
+ {
+ return TYPE_BOUNDED.equals( array.getName( 1 ) );
+ }
+
+ /**
+ * Set if this page destination should just fit the bounding box. The default is false.
+ *
+ * @param fitBoundingBox A flag indicating if this should fit the bounding box.
+ */
+ public void setFitBoundingBox( boolean fitBoundingBox )
+ {
+ array.growToSize( 2 );
+ if( fitBoundingBox )
+ {
+ array.setName( 1, TYPE_BOUNDED );
+ }
+ else
+ {
+ array.setName( 1, TYPE );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitHeightDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitHeightDestination.java
new file mode 100644
index 0000000..64df612
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitHeightDestination.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+
+/**
+ * This represents a destination to a page at a x location and the height is magnified
+ * to just fit on the screen.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageFitHeightDestination extends PDPageDestination
+{
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE = "FitV";
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE_BOUNDED = "FitBV";
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDPageFitHeightDestination()
+ {
+ super();
+ array.growToSize(3);
+ array.setName( 1, TYPE );
+
+ }
+
+ /**
+ * Constructor from an existing destination array.
+ *
+ * @param arr The destination array.
+ */
+ public PDPageFitHeightDestination( COSArray arr )
+ {
+ super( arr );
+ }
+
+ /**
+ * Get the left x coordinate. A return value of -1 implies that the current x-coordinate
+ * will be used.
+ *
+ * @return The left x coordinate.
+ */
+ public int getLeft()
+ {
+ return array.getInt( 2 );
+ }
+
+ /**
+ * Set the left x-coordinate, a value of -1 implies that the current x-coordinate
+ * will be used.
+ * @param x The left x coordinate.
+ */
+ public void setLeft( int x )
+ {
+ array.growToSize( 3 );
+ if( x == -1 )
+ {
+ array.set( 2, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 2, x );
+ }
+ }
+
+ /**
+ * A flag indicating if this page destination should just fit bounding box of the PDF.
+ *
+ * @return true If the destination should fit just the bounding box.
+ */
+ public boolean fitBoundingBox()
+ {
+ return TYPE_BOUNDED.equals( array.getName( 1 ) );
+ }
+
+ /**
+ * Set if this page destination should just fit the bounding box. The default is false.
+ *
+ * @param fitBoundingBox A flag indicating if this should fit the bounding box.
+ */
+ public void setFitBoundingBox( boolean fitBoundingBox )
+ {
+ array.growToSize( 2 );
+ if( fitBoundingBox )
+ {
+ array.setName( 1, TYPE_BOUNDED );
+ }
+ else
+ {
+ array.setName( 1, TYPE );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitRectangleDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitRectangleDestination.java
new file mode 100644
index 0000000..00fc5f1
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitRectangleDestination.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+
+/**
+ * This represents a destination to a page at a y location and the width is magnified
+ * to just fit on the screen.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageFitRectangleDestination extends PDPageDestination
+{
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE = "FitR";
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDPageFitRectangleDestination()
+ {
+ super();
+ array.growToSize(6);
+ array.setName( 1, TYPE );
+
+ }
+
+ /**
+ * Constructor from an existing destination array.
+ *
+ * @param arr The destination array.
+ */
+ public PDPageFitRectangleDestination( COSArray arr )
+ {
+ super( arr );
+ }
+
+ /**
+ * Get the left x coordinate. A return value of -1 implies that the current x-coordinate
+ * will be used.
+ *
+ * @return The left x coordinate.
+ */
+ public int getLeft()
+ {
+ return array.getInt( 2 );
+ }
+
+ /**
+ * Set the left x-coordinate, a value of -1 implies that the current x-coordinate
+ * will be used.
+ * @param x The left x coordinate.
+ */
+ public void setLeft( int x )
+ {
+ array.growToSize( 3 );
+ if( x == -1 )
+ {
+ array.set( 2, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 2, x );
+ }
+ }
+
+ /**
+ * Get the bottom y coordinate. A return value of -1 implies that the current y-coordinate
+ * will be used.
+ *
+ * @return The bottom y coordinate.
+ */
+ public int getBottom()
+ {
+ return array.getInt( 3 );
+ }
+
+ /**
+ * Set the bottom y-coordinate, a value of -1 implies that the current y-coordinate
+ * will be used.
+ * @param y The bottom y coordinate.
+ */
+ public void setBottom( int y )
+ {
+ array.growToSize( 6 );
+ if( y == -1 )
+ {
+ array.set( 3, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 3, y );
+ }
+ }
+
+ /**
+ * Get the right x coordinate. A return value of -1 implies that the current x-coordinate
+ * will be used.
+ *
+ * @return The right x coordinate.
+ */
+ public int getRight()
+ {
+ return array.getInt( 4 );
+ }
+
+ /**
+ * Set the right x-coordinate, a value of -1 implies that the current x-coordinate
+ * will be used.
+ * @param x The right x coordinate.
+ */
+ public void setRight( int x )
+ {
+ array.growToSize( 6 );
+ if( x == -1 )
+ {
+ array.set( 4, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 4, x );
+ }
+ }
+
+
+ /**
+ * Get the top y coordinate. A return value of -1 implies that the current y-coordinate
+ * will be used.
+ *
+ * @return The top y coordinate.
+ */
+ public int getTop()
+ {
+ return array.getInt( 5 );
+ }
+
+ /**
+ * Set the top y-coordinate, a value of -1 implies that the current y-coordinate
+ * will be used.
+ * @param y The top ycoordinate.
+ */
+ public void setTop( int y )
+ {
+ array.growToSize( 6 );
+ if( y == -1 )
+ {
+ array.set( 5, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 5, y );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitWidthDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitWidthDestination.java
new file mode 100644
index 0000000..ef7385f
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageFitWidthDestination.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+
+/**
+ * This represents a destination to a page at a y location and the width is magnified
+ * to just fit on the screen.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageFitWidthDestination extends PDPageDestination
+{
+
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE = "FitH";
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE_BOUNDED = "FitBH";
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDPageFitWidthDestination()
+ {
+ super();
+ array.growToSize(3);
+ array.setName( 1, TYPE );
+
+ }
+
+ /**
+ * Constructor from an existing destination array.
+ *
+ * @param arr The destination array.
+ */
+ public PDPageFitWidthDestination( COSArray arr )
+ {
+ super( arr );
+ }
+
+
+ /**
+ * Get the top y coordinate. A return value of -1 implies that the current y-coordinate
+ * will be used.
+ *
+ * @return The top y coordinate.
+ */
+ public int getTop()
+ {
+ return array.getInt( 2 );
+ }
+
+ /**
+ * Set the top y-coordinate, a value of -1 implies that the current y-coordinate
+ * will be used.
+ * @param y The top ycoordinate.
+ */
+ public void setTop( int y )
+ {
+ array.growToSize( 3 );
+ if( y == -1 )
+ {
+ array.set( 2, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 2, y );
+ }
+ }
+
+ /**
+ * A flag indicating if this page destination should just fit bounding box of the PDF.
+ *
+ * @return true If the destination should fit just the bounding box.
+ */
+ public boolean fitBoundingBox()
+ {
+ return TYPE_BOUNDED.equals( array.getName( 1 ) );
+ }
+
+ /**
+ * Set if this page destination should just fit the bounding box. The default is false.
+ *
+ * @param fitBoundingBox A flag indicating if this should fit the bounding box.
+ */
+ public void setFitBoundingBox( boolean fitBoundingBox )
+ {
+ array.growToSize( 2 );
+ if( fitBoundingBox )
+ {
+ array.setName( 1, TYPE_BOUNDED );
+ }
+ else
+ {
+ array.setName( 1, TYPE );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageXYZDestination.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageXYZDestination.java
new file mode 100644
index 0000000..543a33c
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/PDPageXYZDestination.java
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.destination;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+
+/**
+ * This represents a destination to a page at an x,y coordinate with a zoom setting.
+ * The default x,y,z will be whatever is the current value in the viewer application and
+ * are not required.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDPageXYZDestination extends PDPageDestination
+{
+ /**
+ * The type of this destination.
+ */
+ protected static final String TYPE = "XYZ";
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDPageXYZDestination()
+ {
+ super();
+ array.growToSize(5);
+ array.setName( 1, TYPE );
+
+ }
+
+ /**
+ * Constructor from an existing destination array.
+ *
+ * @param arr The destination array.
+ */
+ public PDPageXYZDestination( COSArray arr )
+ {
+ super( arr );
+ }
+
+ /**
+ * Get the left x coordinate. A return value of -1 implies that the current x-coordinate
+ * will be used.
+ *
+ * @return The left x coordinate.
+ */
+ public int getLeft()
+ {
+ return array.getInt( 2 );
+ }
+
+ /**
+ * Set the left x-coordinate, a value of -1 implies that the current x-coordinate
+ * will be used.
+ * @param x The left x coordinate.
+ */
+ public void setLeft( int x )
+ {
+ array.growToSize( 3 );
+ if( x == -1 )
+ {
+ array.set( 2, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 2, x );
+ }
+ }
+
+ /**
+ * Get the top y coordinate. A return value of -1 implies that the current y-coordinate
+ * will be used.
+ *
+ * @return The top y coordinate.
+ */
+ public int getTop()
+ {
+ return array.getInt( 3 );
+ }
+
+ /**
+ * Set the top y-coordinate, a value of -1 implies that the current y-coordinate
+ * will be used.
+ * @param y The top ycoordinate.
+ */
+ public void setTop( int y )
+ {
+ array.growToSize( 4 );
+ if( y == -1 )
+ {
+ array.set( 3, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 3, y );
+ }
+ }
+
+ /**
+ * Get the zoom value. A return value of -1 implies that the current zoom
+ * will be used.
+ *
+ * @return The zoom value for the page.
+ */
+ public int getZoom()
+ {
+ return array.getInt( 4 );
+ }
+
+ /**
+ * Set the zoom value for the page, a value of -1 implies that the current zoom
+ * will be used.
+ * @param zoom The zoom value.
+ */
+ public void setZoom( int zoom )
+ {
+ array.growToSize( 5 );
+ if( zoom == -1 )
+ {
+ array.set( 4, (COSBase)null );
+ }
+ else
+ {
+ array.setInt( 4, zoom );
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/package.html
new file mode 100644
index 0000000..2122b1d
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/destination/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The destination package allows destinations into a pdf document to be specified.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java
new file mode 100644
index 0000000..157a36f
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.outline;
+
+import org.pdfbox.cos.COSDictionary;
+
+/**
+ * This represents an outline in a pdf document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDDocumentOutline extends PDOutlineNode
+{
+
+ /**
+ * Default Constructor.
+ */
+ public PDDocumentOutline()
+ {
+ super();
+ node.setName( "Type", "Outlines" );
+ }
+
+ /**
+ * Constructor for an existing document outline.
+ *
+ * @param dic The storage dictionary.
+ */
+ public PDDocumentOutline( COSDictionary dic )
+ {
+ super( dic );
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java
new file mode 100644
index 0000000..648eb64
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java
@@ -0,0 +1,425 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.outline;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSFloat;
+import org.pdfbox.exceptions.OutlineNotLocalException;
+import org.pdfbox.pdmodel.PDDestinationNameTreeNode;
+import org.pdfbox.pdmodel.PDDocument;
+import org.pdfbox.pdmodel.PDDocumentNameDictionary;
+import org.pdfbox.pdmodel.PDPage;
+import org.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
+import org.pdfbox.pdmodel.graphics.color.PDColorSpaceInstance;
+import org.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
+import org.pdfbox.pdmodel.interactive.action.type.PDAction;
+import org.pdfbox.pdmodel.interactive.action.type.PDActionGoTo;
+import org.pdfbox.pdmodel.interactive.action.PDActionFactory;
+import org.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
+import org.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination;
+import org.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
+import org.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination;
+
+/**
+ * This represents an outline in a pdf document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.5 $
+ */
+public class PDOutlineItem extends PDOutlineNode
+{
+
+ private static final int ITALIC_FLAG = 1;
+ private static final int BOLD_FLAG = 2;
+
+ /**
+ * Default Constructor.
+ */
+ public PDOutlineItem()
+ {
+ super();
+ }
+
+ /**
+ * Constructor for an existing outline item.
+ *
+ * @param dic The storage dictionary.
+ */
+ public PDOutlineItem( COSDictionary dic )
+ {
+ super( dic );
+ }
+
+ /**
+ * Insert a sibling after this node.
+ *
+ * @param item The item to insert.
+ */
+ public void insertSiblingAfter( PDOutlineItem item )
+ {
+ item.setParent( getParent() );
+ PDOutlineItem next = getNextSibling();
+ setNextSibling( item );
+ item.setPreviousSibling( this );
+ if( next != null )
+ {
+ item.setNextSibling( next );
+ next.setPreviousSibling( item );
+ }
+ updateParentOpenCount( 1 );
+ }
+
+ /**
+ * Return the previous sibling or null if there is no sibling.
+ *
+ * @return The previous sibling.
+ */
+ public PDOutlineItem getPreviousSibling()
+ {
+ PDOutlineItem last = null;
+ COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Prev" );
+ if( lastDic != null )
+ {
+ last = new PDOutlineItem( lastDic );
+ }
+ return last;
+ }
+
+ /**
+ * Set the previous sibling, this will be maintained by this class.
+ *
+ * @param outlineNode The new previous sibling.
+ */
+ protected void setPreviousSibling( PDOutlineNode outlineNode )
+ {
+ node.setItem( "Prev", outlineNode );
+ }
+
+ /**
+ * Return the next sibling or null if there is no next sibling.
+ *
+ * @return The next sibling.
+ */
+ public PDOutlineItem getNextSibling()
+ {
+ PDOutlineItem last = null;
+ COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Next" );
+ if( lastDic != null )
+ {
+ last = new PDOutlineItem( lastDic );
+ }
+ return last;
+ }
+
+ /**
+ * Set the next sibling, this will be maintained by this class.
+ *
+ * @param outlineNode The new next sibling.
+ */
+ protected void setNextSibling( PDOutlineNode outlineNode )
+ {
+ node.setItem( "Next", outlineNode );
+ }
+
+ /**
+ * Get the title of this node.
+ *
+ * @return The title of this node.
+ */
+ public String getTitle()
+ {
+ return node.getString( "Title" );
+ }
+
+ /**
+ * Set the title for this node.
+ *
+ * @param title The new title for this node.
+ */
+ public void setTitle( String title )
+ {
+ node.setString( "Title", title );
+ }
+
+ /**
+ * Get the page destination of this node.
+ *
+ * @return The page destination of this node.
+ * @throws IOException If there is an error creating the destination.
+ */
+ public PDDestination getDestination() throws IOException
+ {
+ return PDDestination.create( node.getDictionaryObject( "Dest" ) );
+ }
+
+ /**
+ * Set the page destination for this node.
+ *
+ * @param dest The new page destination for this node.
+ */
+ public void setDestination( PDDestination dest )
+ {
+ node.setItem( "Dest", dest );
+ }
+
+ /**
+ * A convenience method that will create an XYZ destination using only the defaults.
+ *
+ * @param page The page to refer to.
+ */
+ public void setDestination( PDPage page )
+ {
+ PDPageXYZDestination dest = null;
+ if( page != null )
+ {
+ dest = new PDPageXYZDestination();
+ dest.setPage( page );
+ }
+ setDestination( dest );
+ }
+
+ /**
+ * This method will attempt to find the page in this PDF document that this outline points to.
+ * If the outline does not point to anything then this method will return null. If the outline
+ * is an action that is not a GoTo action then this methods will throw the OutlineNotLocationException
+ *
+ * @param doc The document to get the page from.
+ *
+ * @return The page that this outline will go to when activated or null if it does not point to anything.
+ * @throws IOException If there is an error when trying to find the page.
+ */
+ public PDPage findDestinationPage( PDDocument doc ) throws IOException
+ {
+ PDPage page = null;
+ PDDestination rawDest = getDestination();
+ if( rawDest == null )
+ {
+ PDAction outlineAction = getAction();
+ if( outlineAction instanceof PDActionGoTo )
+ {
+ rawDest = ((PDActionGoTo)outlineAction).getDestination();
+ }
+ else if( outlineAction == null )
+ {
+ //if the outline action is null then this outline does not refer
+ //to anything and we will just return null.
+ }
+ else
+ {
+ throw new OutlineNotLocalException( "Error: Outline does not reference a local page." );
+ }
+ }
+
+ PDPageDestination pageDest = null;
+ if( rawDest instanceof PDNamedDestination )
+ {
+ //if we have a named destination we need to lookup the PDPageDestination
+ PDNamedDestination namedDest = (PDNamedDestination)rawDest;
+ PDDocumentNameDictionary namesDict = doc.getDocumentCatalog().getNames();
+ if( namesDict != null )
+ {
+ PDDestinationNameTreeNode destsTree = namesDict.getDests();
+ if( destsTree != null )
+ {
+ pageDest = (PDPageDestination)destsTree.getValue( namedDest.getNamedDestination() );
+ }
+ }
+ }
+ else if( rawDest instanceof PDPageDestination)
+ {
+ pageDest = (PDPageDestination) rawDest;
+ }
+ else if( rawDest == null )
+ {
+ //if the destination is null then we will simply return a null page.
+ }
+ else
+ {
+ throw new IOException( "Error: Unknown destination type " + rawDest );
+ }
+
+ if( pageDest != null )
+ {
+ page = pageDest.getPage();
+ if( page == null )
+ {
+ int pageNumber = pageDest.getPageNumber();
+ if( pageNumber != -1 )
+ {
+ List allPages = doc.getDocumentCatalog().getAllPages();
+ page = (PDPage)allPages.get( pageNumber );
+ }
+ }
+ }
+
+ return page;
+ }
+
+ /**
+ * Get the action of this node.
+ *
+ * @return The action of this node.
+ */
+ public PDAction getAction()
+ {
+ return PDActionFactory.createAction( (COSDictionary)node.getDictionaryObject( "A" ) );
+ }
+
+ /**
+ * Set the action for this node.
+ *
+ * @param action The new action for this node.
+ */
+ public void setAction( PDAction action )
+ {
+ node.setItem( "A", action );
+ }
+
+ /**
+ * Get the structure element of this node.
+ *
+ * @return The structure element of this node.
+ */
+ public PDStructureElement getStructureElement()
+ {
+ PDStructureElement se = null;
+ COSDictionary dic = (COSDictionary)node.getDictionaryObject( "SE" );
+ if( dic != null )
+ {
+ se = new PDStructureElement( dic );
+ }
+ return se;
+ }
+
+ /**
+ * Set the structure element for this node.
+ *
+ * @param structureElement The new structure element for this node.
+ */
+ public void setAction( PDStructureElement structureElement )
+ {
+ node.setItem( "SE", structureElement );
+ }
+
+ /**
+ * Get the text color of this node. Default is black and this method
+ * will never return null.
+ *
+ * @return The structure element of this node.
+ */
+ public PDColorSpaceInstance getTextColor()
+ {
+ PDColorSpaceInstance retval = null;
+ COSArray csValues = (COSArray)node.getDictionaryObject( "C" );
+ if( csValues == null )
+ {
+ csValues = new COSArray();
+ csValues.growToSize( 3, new COSFloat( 0 ) );
+ node.setItem( "C", csValues );
+ }
+ retval = new PDColorSpaceInstance(csValues);
+ retval.setColorSpace( PDDeviceRGB.INSTANCE );
+ return retval;
+ }
+
+ /**
+ * Set the text color for this node.
+ *
+ * @param textColor The text color for this node.
+ */
+ public void setTextColor( PDColorSpaceInstance textColor )
+ {
+ node.setItem( "C", textColor.getCOSColorSpaceValue() );
+ }
+
+ /**
+ * A flag telling if the text should be italic.
+ *
+ * @return The italic flag.
+ */
+ public boolean isItalic()
+ {
+ return (node.getInt( "F", 0 ) & ITALIC_FLAG) == ITALIC_FLAG;
+ }
+
+ /**
+ * Set the italic property of the text.
+ *
+ * @param italic The new italic flag.
+ */
+ public void setItalic( boolean italic )
+ {
+ int f = node.getInt( "F", 0 );
+ if( italic )
+ {
+ f = f | ITALIC_FLAG;
+ }
+ else
+ {
+ f = f ^ ITALIC_FLAG;
+ }
+ node.setInt( "F", f );
+ }
+
+ /**
+ * A flag telling if the text should be bold.
+ *
+ * @return The bold flag.
+ */
+ public boolean isBold()
+ {
+ return (node.getInt( "F", 0 ) & BOLD_FLAG) == BOLD_FLAG;
+ }
+
+ /**
+ * Set the bold property of the text.
+ *
+ * @param bold The new bold flag.
+ */
+ public void setBold( boolean bold )
+ {
+ int f = node.getInt( "F", 0 );
+ if( bold )
+ {
+ f = f | BOLD_FLAG;
+ }
+ else
+ {
+ f = f ^ BOLD_FLAG;
+ }
+ node.setInt( "F", f );
+ }
+
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java
new file mode 100644
index 0000000..04cc45f
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java
@@ -0,0 +1,320 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.documentnavigation.outline;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * This represents an node in an outline in a pdf document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDOutlineNode implements COSObjectable
+{
+ /**
+ * The dictionary for this node.
+ */
+ protected COSDictionary node;
+
+ /**
+ * Default Constructor.
+ */
+ public PDOutlineNode()
+ {
+ node = new COSDictionary();
+ }
+
+ /**
+ * Default Constructor.
+ *
+ * @param dict The dictionary storage.
+ */
+ public PDOutlineNode( COSDictionary dict)
+ {
+ node = dict;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return node;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSDictionary getCOSDictionary()
+ {
+ return node;
+ }
+
+ /**
+ * Get the parent of this object. This will either be a DocumentOutline or an OutlineItem.
+ *
+ * @return The parent of this object, or null if this is the document outline and there
+ * is no parent.
+ */
+ public PDOutlineNode getParent()
+ {
+ PDOutlineNode retval = null;
+ COSDictionary parent = (COSDictionary)node.getDictionaryObject( "Parent" );
+ if( parent != null )
+ {
+ if( parent.getDictionaryObject( "Parent") == null )
+ {
+ retval = new PDDocumentOutline( parent );
+ }
+ else
+ {
+ retval = new PDOutlineItem( parent );
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * Set the parent of this object, this is maintained by these objects and should not
+ * be called by any clients of PDFBox code.
+ *
+ * @param parent The parent of this object.
+ */
+ protected void setParent( PDOutlineNode parent )
+ {
+ node.setItem( "Parent", parent );
+ }
+
+ /**
+ * append a child node to this node.
+ *
+ * @param outlineNode The node to add.
+ */
+ public void appendChild( PDOutlineItem outlineNode )
+ {
+ outlineNode.setParent( this );
+ if( getFirstChild() == null )
+ {
+ int currentOpenCount = getOpenCount();
+ setFirstChild( outlineNode );
+ //1 for the the item we are adding;
+ int numberOfOpenNodesWeAreAdding = 1;
+ if( outlineNode.isNodeOpen() )
+ {
+ numberOfOpenNodesWeAreAdding += outlineNode.getOpenCount();
+ }
+ if( isNodeOpen() )
+ {
+ setOpenCount( currentOpenCount + numberOfOpenNodesWeAreAdding );
+ }
+ else
+ {
+ setOpenCount( currentOpenCount - numberOfOpenNodesWeAreAdding );
+ }
+ updateParentOpenCount( numberOfOpenNodesWeAreAdding );
+ }
+ else
+ {
+ PDOutlineItem previousLastChild = getLastChild();
+ previousLastChild.insertSiblingAfter( outlineNode );
+ }
+ setLastChild( outlineNode );
+ }
+
+ /**
+ * Return the first child or null if there is no child.
+ *
+ * @return The first child.
+ */
+ public PDOutlineItem getFirstChild()
+ {
+ PDOutlineItem last = null;
+ COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "First" );
+ if( lastDic != null )
+ {
+ last = new PDOutlineItem( lastDic );
+ }
+ return last;
+ }
+
+ /**
+ * Set the first child, this will be maintained by this class.
+ *
+ * @param outlineNode The new first child.
+ */
+ protected void setFirstChild( PDOutlineNode outlineNode )
+ {
+ node.setItem( "First", outlineNode );
+ }
+
+ /**
+ * Return the last child or null if there is no child.
+ *
+ * @return The last child.
+ */
+ public PDOutlineItem getLastChild()
+ {
+ PDOutlineItem last = null;
+ COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Last" );
+ if( lastDic != null )
+ {
+ last = new PDOutlineItem( lastDic );
+ }
+ return last;
+ }
+
+ /**
+ * Set the last child, this will be maintained by this class.
+ *
+ * @param outlineNode The new last child.
+ */
+ protected void setLastChild( PDOutlineNode outlineNode )
+ {
+ node.setItem( "Last", outlineNode );
+ }
+
+ /**
+ * Get the number of open nodes. Or a negative number if this node
+ * is closed. See PDF Reference for more details. This value
+ * is updated as you append children and siblings.
+ *
+ * @return The Count attribute of the outline dictionary.
+ */
+ public int getOpenCount()
+ {
+ return node.getInt( "Count", 0 );
+ }
+
+ /**
+ * Set the open count. This number is automatically managed for you
+ * when you add items to the outline.
+ *
+ * @param openCount The new open cound.
+ */
+ protected void setOpenCount( int openCount )
+ {
+ node.setInt( "Count", openCount );
+ }
+
+ /**
+ * This will set this node to be open when it is shown in the viewer. By default, when
+ * a new node is created it will be closed.
+ * This will do nothing if the node is already open.
+ */
+ public void openNode()
+ {
+ //if the node is already open then do nothing.
+ if( !isNodeOpen() )
+ {
+ int openChildrenCount = 0;
+ PDOutlineItem currentChild = getFirstChild();
+ while( currentChild != null )
+ {
+ //first increase by one for the current child
+ openChildrenCount++;
+ //then increase by the number of open nodes the child has
+ if( currentChild.isNodeOpen() )
+ {
+ openChildrenCount += currentChild.getOpenCount();
+ }
+ currentChild = currentChild.getNextSibling();
+ }
+ setOpenCount( openChildrenCount );
+ updateParentOpenCount( openChildrenCount );
+ }
+ }
+
+ /**
+ * Close this node.
+ *
+ */
+ public void closeNode()
+ {
+ //if the node is already closed then do nothing.
+ if( isNodeOpen() )
+ {
+ int openCount = getOpenCount();
+ updateParentOpenCount( -openCount );
+ setOpenCount( -openCount );
+ }
+ }
+
+ /**
+ * Node is open if the open count is greater than zero.
+ * @return true if this node is open.
+ */
+ public boolean isNodeOpen()
+ {
+ return getOpenCount() > 0;
+ }
+
+ /**
+ * The count parameter needs to be updated when you add or remove elements to
+ * the outline. When you add an element at a lower level then you need to
+ * increase all of the parents.
+ *
+ * @param amount The amount to update by.
+ */
+ protected void updateParentOpenCount( int amount )
+ {
+ PDOutlineNode parent = getParent();
+ if( parent != null )
+ {
+ int currentCount = parent.getOpenCount();
+ //if the currentCount is negative or it is absent then
+ //we will treat it as negative. The default is to be negative.
+ boolean negative = currentCount < 0 ||
+ parent.getCOSDictionary().getDictionaryObject( "Count" ) == null;
+ currentCount = Math.abs( currentCount );
+ currentCount += amount;
+ if( negative )
+ {
+ currentCount = -currentCount;
+ }
+ parent.setOpenCount( currentCount );
+ //recursively call parent to update count, but the parents count is only
+ //updated if this is an open node
+ if( !negative )
+ {
+ parent.updateParentOpenCount( amount );
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/package.html
new file mode 100644
index 0000000..4ec0032
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/outline/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The outline package allows for a PDF outline(bookmarks) to be created.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/package.html
new file mode 100644
index 0000000..b210cf5
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/documentnavigation/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+A package to allow access to document level navigation within a PDF document.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAcroForm.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAcroForm.java
new file mode 100644
index 0000000..4fb576d
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAcroForm.java
@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+
+import org.pdfbox.pdmodel.PDDocument;
+import org.pdfbox.pdmodel.PDResources;
+
+import org.pdfbox.pdmodel.fdf.FDFDictionary;
+import org.pdfbox.pdmodel.fdf.FDFDocument;
+import org.pdfbox.pdmodel.fdf.FDFCatalog;
+import org.pdfbox.pdmodel.fdf.FDFField;
+
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class represents the acroform of a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.8 $
+ */
+public class PDAcroForm
+{
+ private COSDictionary acroForm;
+ private PDDocument document;
+
+ private Map fieldCache;
+
+ /**
+ * Constructor.
+ *
+ * @param doc The document that this form is part of.
+ */
+ public PDAcroForm( PDDocument doc )
+ {
+ document = doc;
+ acroForm = new COSDictionary();
+ COSArray fields = new COSArray();
+ acroForm.setItem( COSName.getPDFName( "Fields" ), fields );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param doc The document that this form is part of.
+ * @param form The existing acroForm.
+ */
+ public PDAcroForm( PDDocument doc, COSDictionary form )
+ {
+ document = doc;
+ acroForm = form;
+ }
+
+ /**
+ * This will get the document associated with this form.
+ *
+ * @return The PDF document.
+ */
+ public PDDocument getDocument()
+ {
+ return document;
+ }
+
+ /**
+ * This will get the dictionary that this form wraps.
+ *
+ * @return The dictionary for this form.
+ */
+ public COSDictionary getDictionary()
+ {
+ return acroForm;
+ }
+
+ /**
+ * This method will import an entire FDF document into the PDF document
+ * that this acroform is part of.
+ *
+ * @param fdf The FDF document to import.
+ *
+ * @throws IOException If there is an error doing the import.
+ */
+ public void importFDF( FDFDocument fdf ) throws IOException
+ {
+ List fields = fdf.getCatalog().getFDF().getFields();
+ if( fields != null )
+ {
+ for( int i=0; i<fields.size(); i++ )
+ {
+ FDFField fdfField = (FDFField)fields.get( i );
+ PDField docField = getField( fdfField.getPartialFieldName() );
+ if( docField != null )
+ {
+ docField.importFDF( fdfField );
+ }
+ }
+ }
+ }
+
+ /**
+ * This will export all FDF form data.
+ *
+ * @return An FDF document used to export the document.
+ * @throws IOException If there is an error when exporting the document.
+ */
+ public FDFDocument exportFDF() throws IOException
+ {
+ FDFDocument fdf = new FDFDocument();
+ FDFCatalog catalog = fdf.getCatalog();
+ FDFDictionary fdfDict = new FDFDictionary();
+ catalog.setFDF( fdfDict );
+
+ List fdfFields = new ArrayList();
+ List fields = getFields();
+ Iterator fieldIter = fields.iterator();
+ while( fieldIter.hasNext() )
+ {
+ PDField docField = (PDField)fieldIter.next();
+ addFieldAndChildren( docField, fdfFields );
+ }
+ fdfDict.setID( document.getDocument().getDocumentID() );
+ if( fdfFields.size() > 0 )
+ {
+ fdfDict.setFields( fdfFields );
+ }
+ return fdf;
+ }
+
+ private void addFieldAndChildren( PDField docField, List fdfFields ) throws IOException
+ {
+ Object fieldValue = docField.getValue();
+ FDFField fdfField = new FDFField();
+ fdfField.setPartialFieldName( docField.getPartialName() );
+ fdfField.setValue( fieldValue );
+ List kids = docField.getKids();
+ List childFDFFields = new ArrayList();
+ if( kids != null )
+ {
+
+ for( int i=0; i<kids.size(); i++ )
+ {
+ addFieldAndChildren( (PDField)kids.get( i ), childFDFFields );
+ }
+ if( childFDFFields.size() > 0 )
+ {
+ fdfField.setKids( childFDFFields );
+ }
+ }
+ if( fieldValue != null || childFDFFields.size() > 0 )
+ {
+ fdfFields.add( fdfField );
+ }
+ }
+
+ /**
+ * This will return all of the fields in the document. The type
+ * will be a org.pdfbox.pdmodel.field.PDField.
+ *
+ * @return A list of all the fields.
+ * @throws IOException If there is an error while getting the list of fields.
+ */
+ public List getFields() throws IOException
+ {
+ COSArray fields =
+ (COSArray) acroForm.getDictionaryObject(
+ COSName.getPDFName("Fields"));
+
+ List retval = new ArrayList();
+ for (int i = 0; i < fields.size(); i++)
+ {
+ COSDictionary element = (COSDictionary) fields.getObject(i);
+ if (element != null)
+ {
+ PDField field = PDFieldFactory.createField( this, element );
+ if( field != null )
+ {
+ retval.add(field);
+ }
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * This will tell this form to cache the fields into a Map structure
+ * for fast access via the getField method. The default is false. You would
+ * want this to be false if you were changing the COSDictionary behind the scenes,
+ * otherwise setting this to true is acceptable.
+ *
+ * @param cache A boolean telling if we should cache the fields.
+ * @throws IOException If there is an error while caching the fields.
+ */
+ public void setCacheFields( boolean cache ) throws IOException
+ {
+ if( cache )
+ {
+ fieldCache = new HashMap();
+ List fields = getFields();
+ Iterator fieldIter = fields.iterator();
+ while( fieldIter.hasNext() )
+ {
+ PDField next = (PDField)fieldIter.next();
+ fieldCache.put( next.getFullyQualifiedName(), next );
+ }
+ }
+ else
+ {
+ fieldCache = null;
+ }
+ }
+
+ /**
+ * This will tell if this acro form is caching the fields.
+ *
+ * @return true if the fields are being cached.
+ */
+ public boolean isCachingFields()
+ {
+ return fieldCache != null;
+ }
+
+ /**
+ * This will get a field by name, possibly using the cache if setCache is true.
+ *
+ * @param name The name of the field to get.
+ *
+ * @return The field with that name of null if one was not found.
+ *
+ * @throws IOException If there is an error getting the field type.
+ */
+ public PDField getField( String name ) throws IOException
+ {
+ PDField retval = null;
+ if( fieldCache != null )
+ {
+ retval = (PDField)fieldCache.get( name );
+ }
+ else
+ {
+ COSArray fields =
+ (COSArray) acroForm.getDictionaryObject(
+ COSName.getPDFName("Fields"));
+
+ for (int i = 0; i < fields.size() && retval == null; i++)
+ {
+ COSDictionary element = (COSDictionary) fields.getObject(i);
+ if( element != null )
+ {
+ COSString fieldName =
+ (COSString)element.getDictionaryObject( COSName.getPDFName( "T" ) );
+ if( fieldName.getString().equals( name ) )
+ {
+ retval = PDFieldFactory.createField( this, element );
+ }
+ }
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * This will get the default resources for the acro form.
+ *
+ * @return The default resources.
+ */
+ public PDResources getDefaultResources()
+ {
+ PDResources retval = null;
+ COSDictionary dr = (COSDictionary)acroForm.getDictionaryObject( COSName.getPDFName( "DR" ) );
+ if( dr != null )
+ {
+ retval = new PDResources( dr );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the default resources for the acroform.
+ *
+ * @param dr The new default resources.
+ */
+ public void setDefaultResources( PDResources dr )
+ {
+ COSDictionary drDict = null;
+ if( dr != null )
+ {
+ drDict = dr.getCOSDictionary();
+ }
+ acroForm.setItem( COSName.getPDFName( "DR" ), drDict );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAppearance.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAppearance.java
new file mode 100644
index 0000000..ff18c86
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDAppearance.java
@@ -0,0 +1,645 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSFloat;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.cos.COSStream;
+import org.pdfbox.cos.COSString;
+
+import org.pdfbox.pdfparser.PDFStreamParser;
+import org.pdfbox.pdfwriter.ContentStreamWriter;
+
+import org.pdfbox.pdmodel.PDResources;
+
+import org.pdfbox.pdmodel.common.PDRectangle;
+
+import org.pdfbox.pdmodel.font.PDFont;
+import org.pdfbox.pdmodel.font.PDFontDescriptor;
+import org.pdfbox.pdmodel.font.PDSimpleFont;
+
+import org.pdfbox.pdmodel.interactive.action.PDAdditionalActions;
+import org.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
+import org.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
+import org.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+
+import org.pdfbox.util.PDFOperator;
+
+/**
+ * This one took me a while, but i'm proud to say that it handles
+ * the appearance of a textbox. This allows you to apply a value to
+ * a field in the document and handle the appearance so that the
+ * value is actually visible too.
+ * The problem was described by Ben Litchfield, the author of the
+ * example: org.pdfbox.examlpes.fdf.ImportFDF. So Ben, here is the
+ * solution.
+ *
+ * @author sug
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.17 $
+ */
+public class PDAppearance
+{
+ private PDVariableText parent;
+
+ private String value;
+ private COSString defaultAppearance;
+
+ private PDAcroForm acroForm;
+ private List widgets = new ArrayList();
+
+
+ /**
+ * Constructs a COSAppearnce from the given field.
+ *
+ * @param theAcroForm the acro form that this field is part of.
+ * @param field the field which you wish to control the appearance of
+ * @throws IOException If there is an error creating the appearance.
+ */
+ public PDAppearance( PDAcroForm theAcroForm, PDVariableText field ) throws IOException
+ {
+ acroForm = theAcroForm;
+ parent = field;
+
+ widgets = field.getKids();
+ if( widgets == null )
+ {
+ widgets = new ArrayList();
+ widgets.add( field.getWidget() );
+ }
+
+ defaultAppearance = getDefaultAppearance();
+
+
+ }
+
+ /**
+ * Returns the default apperance of a textbox. If the textbox
+ * does not have one, then it will be taken from the AcroForm.
+ * @return The DA element
+ */
+ private COSString getDefaultAppearance()
+ {
+
+ COSString dap = parent.getDefaultAppearance();
+ if (dap == null)
+ {
+ COSArray kids = (COSArray)parent.getDictionary().getDictionaryObject( "Kids" );
+ if( kids != null && kids.size() > 0 )
+ {
+ COSDictionary firstKid = (COSDictionary)kids.getObject( 0 );
+ dap = (COSString)firstKid.getDictionaryObject( "DA" );
+ }
+ if( dap == null )
+ {
+ dap = (COSString) acroForm.getDictionary().getDictionaryObject(COSName.getPDFName("DA"));
+ }
+ }
+ return dap;
+ }
+
+ private int getQ()
+ {
+ int q = parent.getQ();
+ if( parent.getDictionary().getDictionaryObject( "Q" ) == null )
+ {
+ COSArray kids = (COSArray)parent.getDictionary().getDictionaryObject( "Kids" );
+ if( kids != null && kids.size() > 0 )
+ {
+ COSDictionary firstKid = (COSDictionary)kids.getObject( 0 );
+ COSNumber qNum = (COSNumber)firstKid.getDictionaryObject( "Q" );
+ if( qNum != null )
+ {
+ q = qNum.intValue();
+ }
+ }
+ }
+ return q;
+ }
+
+ /**
+ * Extracts the original appearance stream into a list of tokens.
+ *
+ * @return The tokens in the original appearance stream
+ */
+ private List getStreamTokens( PDAppearanceStream appearanceStream ) throws IOException
+ {
+ List tokens = null;
+ if( appearanceStream != null )
+ {
+ tokens = getStreamTokens( appearanceStream.getStream() );
+ }
+ return tokens;
+ }
+
+ private List getStreamTokens( COSString string ) throws IOException
+ {
+ PDFStreamParser parser;
+
+ List tokens = null;
+ if( string != null )
+ {
+ ByteArrayInputStream stream = new ByteArrayInputStream( string.getBytes() );
+ parser = new PDFStreamParser( stream, acroForm.getDocument().getDocument().getScratchFile() );
+ parser.parse();
+ tokens = parser.getTokens();
+ }
+ return tokens;
+ }
+
+ private List getStreamTokens( COSStream stream ) throws IOException
+ {
+ PDFStreamParser parser;
+
+ List tokens = null;
+ if( stream != null )
+ {
+ parser = new PDFStreamParser( stream );
+ parser.parse();
+ tokens = parser.getTokens();
+ }
+ return tokens;
+ }
+
+ /**
+ * Tests if the apperance stream already contains content.
+ *
+ * @return true if it contains any content
+ */
+ private boolean containsMarkedContent( List stream )
+ {
+ return stream.contains( PDFOperator.getOperator( "BMC" ) );
+ }
+
+ /**
+ * This is the public method for setting the appearance stream.
+ *
+ * @param apValue the String value which the apperance shoud represent
+ *
+ * @throws IOException If there is an error creating the stream.
+ */
+ public void setAppearanceValue(String apValue) throws IOException
+ {
+ // MulitLine check and set
+ if ( parent.isMultiline() && apValue.indexOf('\n') != -1 )
+ {
+ apValue = convertToMultiLine( apValue );
+ }
+
+ value = apValue;
+ Iterator widgetIter = widgets.iterator();
+ while( widgetIter.hasNext() )
+ {
+ Object next = widgetIter.next();
+ PDAnnotationWidget widget = null;
+ if( next instanceof PDField )
+ {
+ widget = ((PDField)next).getWidget();
+ }
+ else
+ {
+ widget = (PDAnnotationWidget)next;
+ }
+ PDAdditionalActions actions = widget.getActions();
+ if( actions != null &&
+ actions.getF() != null &&
+ widget.getDictionary().getDictionaryObject( "AP" ) ==null)
+ {
+ //do nothing because the field will be formatted by acrobat
+ //when it is opened. See FreedomExpressions.pdf for an example of this.
+ }
+ else
+ {
+
+ PDAppearanceDictionary appearance = widget.getAppearance();
+ if( appearance == null )
+ {
+ appearance = new PDAppearanceDictionary();
+ widget.setAppearance( appearance );
+ }
+
+ Map normalAppearance = appearance.getNormalAppearance();
+ PDAppearanceStream appearanceStream = (PDAppearanceStream)normalAppearance.get( "default" );
+ if( appearanceStream == null )
+ {
+ COSStream cosStream = new COSStream( acroForm.getDocument().getDocument().getScratchFile() );
+ appearanceStream = new PDAppearanceStream( cosStream );
+ appearanceStream.setBoundingBox( widget.getRectangle().createRetranslatedRectangle() );
+ appearance.setNormalAppearance( appearanceStream );
+ }
+
+ List tokens = getStreamTokens( appearanceStream );
+ List daTokens = getStreamTokens( getDefaultAppearance() );
+ PDFont pdFont = getFontAndUpdateResources( tokens, appearanceStream );
+
+ if (!containsMarkedContent( tokens ))
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+ //BJL 9/25/2004 Must prepend existing stream
+ //because it might have operators to draw things like
+ //rectangles and such
+ ContentStreamWriter writer = new ContentStreamWriter( output );
+ writer.writeTokens( tokens );
+
+ output.write( " /Tx BMC\n".getBytes() );
+ insertGeneratedAppearance( widget, output, pdFont, tokens, appearanceStream );
+ output.write( " EMC".getBytes() );
+ writeToStream( output.toByteArray(), appearanceStream );
+ }
+ else
+ {
+ if( tokens != null )
+ {
+ if( daTokens != null )
+ {
+ int bmcIndex = tokens.indexOf( PDFOperator.getOperator( "BMC" ));
+ int emcIndex = tokens.indexOf( PDFOperator.getOperator( "EMC" ));
+ if( bmcIndex != -1 && emcIndex != -1 &&
+ emcIndex == bmcIndex+1 )
+ {
+ //if the EMC immediately follows the BMC index then should
+ //insert the daTokens inbetween the two markers.
+ tokens.addAll( emcIndex, daTokens );
+ }
+ }
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ ContentStreamWriter writer = new ContentStreamWriter( output );
+ float fontSize = calculateFontSize( pdFont, appearanceStream.getBoundingBox(), tokens, null );
+ boolean foundString = false;
+ for( int i=0; i<tokens.size(); i++ )
+ {
+ if( tokens.get( i ) instanceof COSString )
+ {
+ foundString = true;
+ COSString drawnString =((COSString)tokens.get(i));
+ drawnString.reset();
+ drawnString.append( apValue.getBytes() );
+ }
+ }
+ int setFontIndex = tokens.indexOf( PDFOperator.getOperator( "Tf" ));
+ tokens.set( setFontIndex-1, new COSFloat( fontSize ) );
+ if( foundString )
+ {
+ writer.writeTokens( tokens );
+ }
+ else
+ {
+ int bmcIndex = tokens.indexOf( PDFOperator.getOperator( "BMC" ) );
+ int emcIndex = tokens.indexOf( PDFOperator.getOperator( "EMC" ) );
+
+ if( bmcIndex != -1 )
+ {
+ writer.writeTokens( tokens, 0, bmcIndex+1 );
+ }
+ else
+ {
+ writer.writeTokens( tokens );
+ }
+ output.write( "\n".getBytes() );
+ insertGeneratedAppearance( widget, output,
+ pdFont, tokens, appearanceStream );
+ if( emcIndex != -1 )
+ {
+ writer.writeTokens( tokens, emcIndex, tokens.size() );
+ }
+ }
+ writeToStream( output.toByteArray(), appearanceStream );
+ }
+ else
+ {
+ //hmm?
+ }
+ }
+ }
+ }
+ }
+
+ private void insertGeneratedAppearance( PDAnnotationWidget fieldWidget, OutputStream output,
+ PDFont pdFont, List tokens, PDAppearanceStream appearanceStream ) throws IOException
+ {
+ PrintWriter printWriter = new PrintWriter( output, true );
+ float fontSize = 0.0f;
+ PDRectangle boundingBox = null;
+ boundingBox = appearanceStream.getBoundingBox();
+ if( boundingBox == null )
+ {
+ boundingBox = fieldWidget.getRectangle().createRetranslatedRectangle();
+ }
+ printWriter.println( "BT" );
+ if( defaultAppearance != null )
+ {
+ String daString = defaultAppearance.getString();
+ PDFStreamParser daParser = new PDFStreamParser(new ByteArrayInputStream( daString.getBytes() ), null );
+ daParser.parse();
+ List daTokens = daParser.getTokens();
+ fontSize = calculateFontSize( pdFont, boundingBox, tokens, daTokens );
+ int fontIndex = daTokens.indexOf( PDFOperator.getOperator( "Tf" ) );
+ if(fontIndex != -1 )
+ {
+ daTokens.set( fontIndex-1, new COSFloat( fontSize ) );
+ }
+ ContentStreamWriter daWriter = new ContentStreamWriter(output);
+ daWriter.writeTokens( daTokens );
+ }
+ printWriter.println( getTextPosition( boundingBox, pdFont, fontSize, tokens ) );
+ int q = getQ();
+ if( q == PDTextbox.QUADDING_LEFT )
+ {
+ //do nothing because left is default
+ }
+ else if( q == PDTextbox.QUADDING_CENTERED ||
+ q == PDTextbox.QUADDING_RIGHT )
+ {
+ float fieldWidth = boundingBox.getWidth();
+ float stringWidth = (pdFont.getStringWidth( value )/1000)*fontSize;
+ float adjustAmount = fieldWidth - stringWidth - 4;
+
+ if( q == PDTextbox.QUADDING_CENTERED )
+ {
+ adjustAmount = adjustAmount/2.0f;
+ }
+
+ printWriter.println( adjustAmount + " 0 Td" );
+ }
+ else
+ {
+ throw new IOException( "Error: Unknown justification value:" + q );
+ }
+ printWriter.println("(" + value + ") Tj");
+ printWriter.println("ET" );
+ printWriter.flush();
+ }
+
+ private PDFont getFontAndUpdateResources( List tokens, PDAppearanceStream appearanceStream ) throws IOException
+ {
+
+ PDFont retval = null;
+ PDResources streamResources = appearanceStream.getResources();
+ PDResources formResources = acroForm.getDefaultResources();
+ if( formResources != null )
+ {
+ if( streamResources == null )
+ {
+ streamResources = new PDResources();
+ appearanceStream.setResources( streamResources );
+ }
+
+ COSString da = getDefaultAppearance();
+ if( da != null )
+ {
+ String data = da.getString();
+ PDFStreamParser streamParser = new PDFStreamParser(
+ new ByteArrayInputStream( data.getBytes() ), null );
+ streamParser.parse();
+ tokens = streamParser.getTokens();
+ }
+
+ int setFontIndex = tokens.indexOf( PDFOperator.getOperator( "Tf" ));
+ COSName cosFontName = (COSName)tokens.get( setFontIndex-2 );
+ String fontName = cosFontName.getName();
+ retval = (PDFont)streamResources.getFonts().get( fontName );
+ if( retval == null )
+ {
+ retval = (PDFont)formResources.getFonts().get( fontName );
+ streamResources.getFonts().put( fontName, retval );
+ }
+ }
+ return retval;
+ }
+
+ private String convertToMultiLine( String line )
+ {
+ int currIdx = 0;
+ int lastIdx = 0;
+ StringBuffer result = new StringBuffer(line.length() + 64);
+ while( (currIdx = line.indexOf('\n',lastIdx )) > -1 )
+ {
+ result.append(value.substring(lastIdx,currIdx));
+ result.append(" ) Tj\n0 -13 Td\n(");
+ lastIdx = currIdx + 1;
+ }
+ result.append(line.substring(lastIdx));
+ return result.toString();
+ }
+
+ /**
+ * Writes the stream to the actual stream in the COSStream.
+ *
+ * @throws IOException If there is an error writing to the stream
+ */
+ private void writeToStream( byte[] data, PDAppearanceStream appearanceStream ) throws IOException
+ {
+ OutputStream out = appearanceStream.getStream().createUnfilteredStream();
+ out.write( data );
+ out.flush();
+ }
+
+
+ /**
+ * w in an appearance stream represents the lineWidth.
+ * @return the linewidth
+ */
+ private float getLineWidth( List tokens )
+ {
+
+ float retval = 1;
+ if( tokens != null )
+ {
+ int btIndex = tokens.indexOf(PDFOperator.getOperator( "BT" ));
+ int wIndex = tokens.indexOf(PDFOperator.getOperator( "w" ));
+ //the w should only be used if it is before the first BT.
+ if( (wIndex > 0) && (wIndex < btIndex) )
+ {
+ retval = ((COSNumber)tokens.get(wIndex-1)).floatValue();
+ }
+ }
+ return retval;
+ }
+
+ private PDRectangle getSmallestDrawnRectangle( PDRectangle boundingBox, List tokens )
+ {
+ PDRectangle smallest = boundingBox;
+ for( int i=0; i<tokens.size(); i++ )
+ {
+ Object next = tokens.get( i );
+ if( next == PDFOperator.getOperator( "re" ) )
+ {
+ COSNumber x = (COSNumber)tokens.get( i-4 );
+ COSNumber y = (COSNumber)tokens.get( i-3 );
+ COSNumber width = (COSNumber)tokens.get( i-2 );
+ COSNumber height = (COSNumber)tokens.get( i-1 );
+ PDRectangle potentialSmallest = new PDRectangle();
+ potentialSmallest.setLowerLeftX( x.floatValue() );
+ potentialSmallest.setLowerLeftY( y.floatValue() );
+ potentialSmallest.setUpperRightX( x.floatValue() + width.floatValue() );
+ potentialSmallest.setUpperRightY( y.floatValue() + height.floatValue() );
+ if( smallest == null ||
+ smallest.getLowerLeftX() < potentialSmallest.getLowerLeftX() ||
+ smallest.getUpperRightY() > potentialSmallest.getUpperRightY() )
+ {
+ smallest = potentialSmallest;
+ }
+
+ }
+ }
+ return smallest;
+ }
+
+ /**
+ * My "not so great" method for calculating the fontsize.
+ * It does not work superb, but it handles ok.
+ * @return the calculated font-size
+ *
+ * @throws IOException If there is an error getting the font height.
+ */
+ private float calculateFontSize( PDFont pdFont, PDRectangle boundingBox, List tokens, List daTokens )
+ throws IOException
+ {
+ float fontSize = 0;
+ if( daTokens != null )
+ {
+ //daString looks like "BMC /Helv 3.4 Tf EMC"
+
+ int fontIndex = daTokens.indexOf( PDFOperator.getOperator( "Tf" ) );
+ if(fontIndex != -1 )
+ {
+ fontSize = ((COSNumber)daTokens.get(fontIndex-1)).floatValue();
+ }
+ }
+ if( parent.doNotScroll() )
+ {
+ //if we don't scroll then we will shrink the font to fit into the text area.
+ float widthAtFontSize1 = pdFont.getStringWidth( value );
+ float availableWidth = boundingBox.getWidth();
+ float perfectFitFontSize = availableWidth / widthAtFontSize1;
+ }
+ else if( fontSize == 0 )
+ {
+ float lineWidth = getLineWidth( tokens );
+ float stringWidth = pdFont.getStringWidth( value );
+ float height = 0;
+ if( pdFont instanceof PDSimpleFont )
+ {
+ height = ((PDSimpleFont)pdFont).getFontDescriptor().getFontBoundingBox().getHeight();
+ }
+ else
+ {
+ //now much we can do, so lets assume font is square and use width
+ //as the height
+ height = pdFont.getAverageFontWidth();
+ }
+ height = height/1000f;
+
+ float availHeight = getAvailableHeight( boundingBox, lineWidth );
+ fontSize =(availHeight/height);
+ }
+ return fontSize;
+ }
+
+ /**
+ * Calculates where to start putting the text in the box.
+ * The positioning is not quite as accurate as when Acrobat
+ * places the elements, but it works though.
+ *
+ * @return the sting for representing the start position of the text
+ *
+ * @throws IOException If there is an error calculating the text position.
+ */
+ private String getTextPosition( PDRectangle boundingBox, PDFont pdFont, float fontSize, List tokens )
+ throws IOException
+ {
+ float lineWidth = getLineWidth( tokens );
+ float pos = 0.0f;
+ if(parent.isMultiline())
+ {
+ int rows = (int) (getAvailableHeight( boundingBox, lineWidth ) / ((int) fontSize));
+ pos = ((rows)*fontSize)-fontSize;
+ }
+ else
+ {
+ if( pdFont instanceof PDSimpleFont )
+ {
+ //BJL 9/25/2004
+ //This algorithm is a little bit of black magic. It does
+ //not appear to be documented anywhere. Through examining a few
+ //PDF documents and the value that Acrobat places in there I
+ //have determined that the below method of computing the position
+ //is correct for certain documents, but maybe not all. It does
+ //work f1040ez.pdf and Form_1.pdf
+ PDFontDescriptor fd = ((PDSimpleFont)pdFont).getFontDescriptor();
+ float bBoxHeight = boundingBox.getHeight();
+ float fontHeight = fd.getFontBoundingBox().getHeight() + 2 * fd.getDescent();
+ fontHeight = (fontHeight/1000) * fontSize;
+ pos = (bBoxHeight - fontHeight)/2;
+ }
+ else
+ {
+ throw new IOException( "Error: Don't know how to calculate the position for non-simple fonts" );
+ }
+ }
+ PDRectangle innerBox = getSmallestDrawnRectangle( boundingBox, tokens );
+ float xInset = 2+ 2*(boundingBox.getWidth() - innerBox.getWidth());
+ return Math.round(xInset) + " "+ pos + " Td";
+ }
+
+ /**
+ * calculates the available width of the box.
+ * @return the calculated available width of the box
+ */
+ private float getAvailableWidth( PDRectangle boundingBox, float lineWidth )
+ {
+ return boundingBox.getWidth() - 2 * lineWidth;
+ }
+
+ /**
+ * calculates the available height of the box.
+ * @return the calculated available height of the box
+ */
+ private float getAvailableHeight( PDRectangle boundingBox, float lineWidth )
+ {
+ return boundingBox.getHeight() - 2 * lineWidth;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDCheckbox.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDCheckbox.java
new file mode 100644
index 0000000..2e175d0
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDCheckbox.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2003-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A class for handling the PDF field as a checkbox.
+ *
+ * @author sug
+ * @version $Revision: 1.10 $
+ */
+public class PDCheckbox extends PDChoiceButton
+{
+ private static final COSName KEY = COSName.getPDFName("AS");
+ private static final COSName OFF_VALUE = COSName.getPDFName("Off");
+
+ private COSName value;
+
+ /**
+ * @see PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The checkbox field dictionary
+ */
+ public PDCheckbox( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super( theAcroForm, field);
+ COSDictionary ap = (COSDictionary) field.getDictionaryObject(COSName.getPDFName("AP"));
+ if( ap != null )
+ {
+ COSBase n = ap.getDictionaryObject(COSName.getPDFName("N"));
+
+ if( n instanceof COSDictionary )
+ {
+ List li = ((COSDictionary)n).keyList();
+ for( int i=0; i<li.size(); i++ )
+ {
+ COSName name = (COSName)li.get( i );
+ if( !name.equals( OFF_VALUE ))
+ {
+ value = name;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ value = (COSName)getDictionary().getDictionaryObject( "V" );
+ }
+ }
+
+ /**
+ * This will tell if this radio button is currently checked or not.
+ *
+ * @return true If the radio button is checked.
+ */
+ public boolean isChecked()
+ {
+ boolean retval = false;
+ String onValue = getOnValue();
+ COSName radioValue = (COSName)getDictionary().getDictionaryObject( KEY );
+ if( radioValue != null && value != null && radioValue.getName().equals( onValue ) )
+ {
+ retval = true;
+ }
+
+ return retval;
+ }
+
+ /**
+ * Checks the radiobutton.
+ */
+ public void check()
+ {
+ getDictionary().setItem(KEY, value);
+ }
+
+ /**
+ * Unchecks the radiobutton.
+ */
+ public void unCheck()
+ {
+ getDictionary().setItem(KEY, OFF_VALUE);
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#setValue(java.lang.String)
+ */
+ public void setValue(String newValue)
+ {
+ getDictionary().setName( "V", newValue );
+ if( newValue == null )
+ {
+ getDictionary().setItem( KEY, OFF_VALUE );
+ }
+ else
+ {
+ getDictionary().setName( KEY, newValue );
+ }
+ }
+
+ /**
+ * This will get the value of the radio button.
+ *
+ * @return The value of the radio button.
+ */
+ public String getOffValue()
+ {
+ return OFF_VALUE.getName();
+ }
+
+ /**
+ * This will get the value of the radio button.
+ *
+ * @return The value of the radio button.
+ */
+ public String getOnValue()
+ {
+ String retval = null;
+ COSDictionary ap = (COSDictionary) getDictionary().getDictionaryObject(COSName.getPDFName("AP"));
+ COSBase n = ap.getDictionaryObject(COSName.getPDFName("N"));
+
+ //N can be a COSDictionary or a COSStream
+ if( n instanceof COSDictionary )
+ {
+ Iterator li = ((COSDictionary)n).keyList().iterator();
+ while( li.hasNext() )
+ {
+ Object key = li.next();
+ if( !key.equals( OFF_VALUE) )
+ {
+ retval = ((COSName)key).getName();
+ }
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * getValue gets the fields value to as a string.
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error getting the value.
+ */
+ public String getValue() throws IOException
+ {
+ return getDictionary().getNameAsString( "V" );
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceButton.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceButton.java
new file mode 100644
index 0000000..5196d85
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceButton.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+
+import org.pdfbox.pdmodel.common.COSArrayList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This holds common functionality for check boxes and radio buttons.
+ *
+ * @author sug
+ * @version $Revision: 1.4 $
+ */
+public abstract class PDChoiceButton extends PDField
+{
+
+ /**
+ * @see PDField#PDField(PDAcroForm,org.pdfbox.cos.COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field for this button.
+ */
+ public PDChoiceButton( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super(theAcroForm, field);
+ }
+
+ /**
+ * This will get the option values "Opt" entry of the pdf button.
+ *
+ * @return A list of java.lang.String values.
+ */
+ public List getOptions()
+ {
+ List retval = null;
+ COSArray array = (COSArray)getDictionary().getDictionaryObject( COSName.getPDFName( "Opt" ) );
+ if( array != null )
+ {
+ List strings = new ArrayList();
+ for( int i=0; i<array.size(); i++ )
+ {
+ strings.add( ((COSString)array.getObject( i )).getString() );
+ }
+ retval = new COSArrayList( strings, array );
+ }
+ return retval;
+ }
+
+ /**
+ * This will will set the list of options for this button.
+ *
+ * @param options The list of options for the button.
+ */
+ public void setOptions( List options )
+ {
+ getDictionary().setItem(
+ COSName.getPDFName( "Opt" ),
+ COSArrayList.converterToCOSArray( options ) );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceField.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceField.java
new file mode 100644
index 0000000..ff02cc6
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDChoiceField.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+import org.pdfbox.cos.COSInteger;
+
+/**
+ * A class for handling the PDF field as a choicefield.
+ *
+ * @author sug
+ * @version $Revision: 1.6 $
+ */
+public class PDChoiceField extends PDVariableText
+{
+
+ /**
+ * @see org.pdfbox.pdmodel.field.PDField#COSField(org.pdfbox.cos.COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field for this choice field.
+ */
+ public PDChoiceField( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super(theAcroForm, field);
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.field.PDField#setValue(java.lang.String)
+ *
+ * @param optionValue The new value for this text field.
+ *
+ * @throws IOException If there is an error calculating the appearance stream or the value in not one
+ * of the existing options.
+ */
+ public void setValue(String optionValue) throws IOException
+ {
+ int indexSelected = -1;
+ COSArray options = (COSArray)getDictionary().getDictionaryObject( "Opt" );
+ if( options.size() == 0 )
+ {
+ throw new IOException( "Error: You cannot set a value for a choice field if there are no options." );
+ }
+ else
+ {
+ COSBase option = options.getObject( 0 );
+ if( option instanceof COSArray )
+ {
+ for( int i=0; i<options.size() && indexSelected == -1; i++ )
+ {
+ COSArray keyValuePair = (COSArray)options.get( i );
+ COSString key = (COSString)keyValuePair.getObject( 0 );
+ COSString value = (COSString)keyValuePair.getObject( 1 );
+ if( optionValue.equals( key.getString() ) || optionValue.equals( value.getString() ) )
+ {
+ //have the parent draw the appearance stream with the value
+ super.setValue( value.getString() );
+ //but then use the key as the V entry
+ getDictionary().setItem( COSName.getPDFName( "V" ), key );
+ indexSelected = i;
+ }
+ }
+ }
+ else
+ {
+ for( int i=0; i<options.size() && indexSelected == -1; i++ )
+ {
+ COSString value = (COSString)options.get( i );
+ if( optionValue.equals( value.getString() ) )
+ {
+ setValue( optionValue );
+ indexSelected = i;
+ }
+ }
+ }
+ }
+ if( indexSelected == -1 )
+ {
+ throw new IOException( "Error: '" + optionValue + "' was not an available option.");
+ }
+ else
+ {
+ COSArray indexArray = (COSArray)getDictionary().getDictionaryObject( "I" );
+ if( indexArray != null )
+ {
+ indexArray.clear();
+ indexArray.add( new COSInteger( indexSelected ) );
+ }
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDField.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDField.java
new file mode 100644
index 0000000..c395794
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDField.java
@@ -0,0 +1,610 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
+import org.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+
+import org.pdfbox.pdmodel.common.COSArrayList;
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSInteger;
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.pdmodel.common.PDTextStream;
+
+import org.pdfbox.pdmodel.fdf.FDFField;
+import org.pdfbox.util.BitFlagHelper;
+
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the superclass for a Field element in a PDF.
+ * Based on the COS object model from PDFBox.
+ *
+ * @author sug
+ * @version $Revision: 1.21 $
+ */
+public abstract class PDField implements COSObjectable
+{
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_READ_ONLY = 1;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_REQUIRED = 1 << 1;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_NO_EXPORT = 1 << 2;
+
+
+ private PDAcroForm acroForm;
+
+ private COSDictionary dictionary;
+
+ /**
+ * Constructor.
+ *
+ * @param theAcroForm The form that this field is part of.
+ */
+ public PDField( PDAcroForm theAcroForm )
+ {
+ acroForm = theAcroForm;
+ dictionary = new COSDictionary();
+ //no required fields in base field class
+ }
+
+
+ /**
+ * Creates a COSField from a COSDictionary, expected to be
+ * a correct object definition for a field in PDF.
+ *
+ * @param theAcroForm The form that this field is part of.
+ * @param field the PDF objet to represent as a field.
+ */
+ public PDField(PDAcroForm theAcroForm, COSDictionary field)
+ {
+ acroForm = theAcroForm;
+ dictionary = field;
+ }
+
+ /**
+ * Returns the partial name of the field.
+ *
+ * @return the name of the field
+ */
+ public String getPartialName()
+ {
+ return getDictionary().getString( "T" );
+ }
+
+ /**
+ * This will set the partial name of the field.
+ *
+ * @param name The new name for the field.
+ */
+ public void setPartialName( String name )
+ {
+ getDictionary().setString( "T", name );
+ }
+
+ /**
+ * Returns the fully qualified name of the field, which is a concatenation of
+ * the names of all the parents fields.
+ *
+ * @return the name of the field
+ *
+ * @throws IOException If there is an error generating the fully qualified name.
+ */
+ public String getFullyQualifiedName() throws IOException
+ {
+ PDField parent = getParent();
+ String parentName = null;
+ if( parent != null )
+ {
+ parentName = parent.getFullyQualifiedName();
+ }
+ String finalName = getPartialName();
+ if( parentName != null )
+ {
+ finalName = parentName + "." + finalName;
+ }
+ return finalName;
+ }
+
+ /**
+ * Get the FT entry of the field. This is a read only field and is set depending
+ * on the actual type. The field type is an inheritable attribute. This method will
+ * return only the direct value on this object. Use the findFieldType for an upward
+ * recursive search.
+ *
+ * @return The Field type.
+ *
+ * @see PDField#findFieldType()
+ */
+ public String getFieldType()
+ {
+ return getDictionary().getNameAsString( "FT" );
+ }
+
+ /**
+ * Find the field type and optionally do a recursive upward search. Sometimes the fieldtype
+ * will be specified on the parent instead of the direct object. This will look at this
+ * object for the field type, if none is specified then it will look to the parent if there
+ * is a parent. If there is no parent and no field type has been found then this
+ * will return null.
+ *
+ * @return The field type or null if none was found.
+ */
+ public String findFieldType()
+ {
+ return findFieldType( getDictionary() );
+ }
+
+ private String findFieldType( COSDictionary dic )
+ {
+ String retval = dic.getNameAsString( "FT" );
+ if( retval == null )
+ {
+ COSDictionary parent = (COSDictionary)dic.getDictionaryObject( "Parent" );
+ if( parent != null )
+ {
+ retval = findFieldType( parent );
+ }
+ }
+ return retval;
+
+ }
+
+
+ /**
+ * setValue sets the fields value to a given string.
+ *
+ * @param value the string value
+ *
+ * @throws IOException If there is an error creating the appearance stream.
+ */
+ public abstract void setValue(String value) throws IOException;
+
+ /**
+ * getValue gets the fields value to as a string.
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error getting the value.
+ */
+ public abstract String getValue() throws IOException;
+
+ /**
+ * sets the field to be read-only.
+ *
+ * @param readonly The new flag for readonly.
+ */
+ public void setReadonly(boolean readonly)
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_READ_ONLY, readonly );
+ }
+
+ /**
+ *
+ * @return true if the field is readonly
+ */
+ public boolean isReadonly()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_READ_ONLY );
+ }
+
+ /**
+ * sets the field to be required.
+ *
+ * @param required The new flag for required.
+ */
+ public void setRequired(boolean required)
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_REQUIRED, required );
+ }
+
+ /**
+ *
+ * @return true if the field is required
+ */
+ public boolean isRequired()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_REQUIRED );
+ }
+
+ /**
+ * sets the field to be not exported..
+ *
+ * @param noExport The new flag for noExport.
+ */
+ public void setNoExport(boolean noExport)
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_NO_EXPORT, noExport );
+ }
+
+ /**
+ *
+ * @return true if the field is not to be exported.
+ */
+ public boolean isNoExport()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_NO_EXPORT );
+ }
+
+ /**
+ * This will get the flags for this field.
+ *
+ * @return flags The set of flags.
+ */
+ public int getFieldFlags()
+ {
+ int retval = 0;
+ COSInteger ff = (COSInteger)getDictionary().getDictionaryObject( COSName.getPDFName( "Ff" ) );
+ if( ff != null )
+ {
+ retval = ff.intValue();
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the flags for this field.
+ *
+ * @param flags The new flags.
+ */
+ public void setFieldFlags( int flags )
+ {
+ COSInteger ff = new COSInteger( flags );
+ getDictionary().setItem( COSName.getPDFName( "Ff" ), ff );
+ }
+
+ /**
+ * This will import a fdf field from a fdf document.
+ *
+ * @param fdfField The fdf field to import.
+ *
+ * @throws IOException If there is an error importing the data for this field.
+ */
+ public void importFDF( FDFField fdfField ) throws IOException
+ {
+ Object fieldValue = fdfField.getValue();
+ int fieldFlags = getFieldFlags();
+
+ if( fieldValue != null )
+ {
+ if( fieldValue instanceof String )
+ {
+ setValue( (String)fieldValue );
+ }
+ else if( fieldValue instanceof PDTextStream )
+ {
+ setValue( ((PDTextStream)fieldValue).getAsString() );
+ }
+ else
+ {
+ throw new IOException( "Unknown field type:" + fieldValue.getClass().getName() );
+ }
+ }
+ Integer ff = fdfField.getFieldFlags();
+ if( ff != null )
+ {
+ setFieldFlags( ff.intValue() );
+ }
+ else
+ {
+ //these are suppose to be ignored if the Ff is set.
+ Integer setFf = fdfField.getSetFieldFlags();
+
+ if( setFf != null )
+ {
+ int setFfInt = setFf.intValue();
+ fieldFlags = fieldFlags | setFfInt;
+ setFieldFlags( fieldFlags );
+ }
+
+ Integer clrFf = fdfField.getClearFieldFlags();
+ if( clrFf != null )
+ {
+ //we have to clear the bits of the document fields for every bit that is
+ //set in this field.
+ //
+ //Example:
+ //docFf = 1011
+ //clrFf = 1101
+ //clrFfValue = 0010;
+ //newValue = 1011 & 0010 which is 0010
+ int clrFfValue = clrFf.intValue();
+ clrFfValue ^= 0xFFFFFFFF;
+ fieldFlags = fieldFlags & clrFfValue;
+ setFieldFlags( fieldFlags );
+ }
+ }
+
+ PDAnnotationWidget widget = getWidget();
+ if( widget != null )
+ {
+ int annotFlags = widget.getAnnotationFlags();
+ Integer f = fdfField.getWidgetFieldFlags();
+ if( f != null && widget != null )
+ {
+ widget.setAnnotationFlags( f.intValue() );
+ }
+ else
+ {
+ //these are suppose to be ignored if the F is set.
+ Integer setF = fdfField.getSetWidgetFieldFlags();
+ if( setF != null )
+ {
+ annotFlags = annotFlags | setF.intValue();
+ widget.setAnnotationFlags( annotFlags );
+ }
+
+ Integer clrF = fdfField.getClearWidgetFieldFlags();
+ if( clrF != null )
+ {
+ //we have to clear the bits of the document fields for every bit that is
+ //set in this field.
+ //
+ //Example:
+ //docF = 1011
+ //clrF = 1101
+ //clrFValue = 0010;
+ //newValue = 1011 & 0010 which is 0010
+ int clrFValue = clrF.intValue();
+ clrFValue ^= 0xFFFFFFFFL;
+ annotFlags = annotFlags & clrFValue;
+ widget.setAnnotationFlags( annotFlags );
+ }
+ }
+ }
+ List fdfKids = fdfField.getKids();
+ List pdKids = getKids();
+ for( int i=0; fdfKids != null && i<fdfKids.size(); i++ )
+ {
+ FDFField fdfChild = (FDFField)fdfKids.get( i );
+ String fdfName = fdfChild.getPartialFieldName();
+ for( int j=0; j<pdKids.size(); j++ )
+ {
+ Object pdChildObj = pdKids.get( j );
+ if( pdChildObj instanceof PDField )
+ {
+ PDField pdChild = (PDField)pdChildObj;
+ if( fdfName != null && fdfName.equals( pdChild.getPartialName() ) )
+ {
+ pdChild.importFDF( fdfChild );
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This will get the single associated widget that is part of this field. This
+ * occurs when the Widget is embedded in the fields dictionary. Sometimes there
+ * are multiple sub widgets associated with this field, in which case you want to
+ * use getKids(). If the kids entry is specified, then the first entry in that
+ * list will be returned.
+ *
+ * @return The widget that is associated with this field.
+ * @throws IOException If there is an error getting the widget object.
+ */
+ public PDAnnotationWidget getWidget() throws IOException
+ {
+ PDAnnotationWidget retval = null;
+ List kids = getKids();
+ if( kids == null )
+ {
+ retval = new PDAnnotationWidget( getDictionary() );
+ }
+ else if( kids.size() > 0 )
+ {
+ Object firstKid = kids.get( 0 );
+ if( firstKid instanceof PDAnnotationWidget )
+ {
+ retval = (PDAnnotationWidget)firstKid;
+ }
+ else
+ {
+ retval = ((PDField)firstKid).getWidget();
+ }
+ }
+ else
+ {
+ retval = null;
+ }
+ return retval;
+ }
+
+ /**
+ * Get the parent field to this field, or null if none exists.
+ *
+ * @return The parent field.
+ *
+ * @throws IOException If there is an error creating the parent field.
+ */
+ public PDField getParent() throws IOException
+ {
+ PDField parent = null;
+ COSDictionary parentDic = (COSDictionary)getDictionary().getDictionaryObject( "Parent" );
+ if( parentDic != null )
+ {
+ parent = PDFieldFactory.createField( getAcroForm(), parentDic );
+ }
+ return parent;
+ }
+
+ /**
+ * Set the parent of this field.
+ *
+ * @param parent The parent to this field.
+ */
+ public void setParent( PDField parent )
+ {
+ getDictionary().setItem( "Parent", parent );
+ }
+
+ /**
+ * This will get all the kids of this field. The values in the list
+ * will either be PDWidget or PDField. Normally they will be PDWidget objects
+ * unless this is a non-terminal field and they will be child PDField objects.
+ *
+ * @return A list of either PDWidget or PDField objects.
+ * @throws IOException If there is an error retrieving the kids.
+ */
+ public List getKids() throws IOException
+ {
+ List retval = null;
+ COSArray kids = (COSArray)getDictionary().getDictionaryObject(COSName.KIDS);
+ if( kids != null )
+ {
+ List kidsList = new ArrayList();
+ for (int i = 0; i < kids.size(); i++)
+ {
+ COSDictionary kidDictionary = (COSDictionary)kids.getObject(i);
+ COSDictionary parent = (COSDictionary)kidDictionary.getDictionaryObject( "Parent" );
+ if( kidDictionary.getDictionaryObject( "FT" ) != null ||
+ (parent != null && parent.getDictionaryObject( "FT" ) != null ) )
+ {
+ kidsList.add( PDFieldFactory.createField( acroForm, kidDictionary ));
+ }
+ else if( "Widget".equals( kidDictionary.getNameAsString( "Subtype" ) ) )
+ {
+ kidsList.add( new PDAnnotationWidget( kidDictionary ) );
+ }
+ else
+ {
+ //
+ kidsList.add( PDFieldFactory.createField( acroForm, kidDictionary ));
+ }
+ }
+ retval = new COSArrayList( kidsList, kids );
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the list of kids.
+ *
+ * @param kids The list of child widgets.
+ */
+ public void setKids( List kids )
+ {
+ COSArray kidsArray = COSArrayList.converterToCOSArray( kids );
+ getDictionary().setItem( COSName.KIDS, kidsArray );
+ }
+
+ /**
+ * This will return a string representation of this field.
+ *
+ * @return A string representation of this field.
+ */
+ public String toString()
+ {
+ return "" + getDictionary().getDictionaryObject( COSName.getPDFName( "V" ) );
+ }
+
+ /**
+ * This will get the acroform that this field is part of.
+ *
+ * @return The form this field is on.
+ */
+ public PDAcroForm getAcroForm()
+ {
+ return acroForm;
+ }
+
+ /**
+ * This will set the form this field is on.
+ *
+ * @param value The new form to use.
+ */
+ public void setAcroForm(PDAcroForm value)
+ {
+ acroForm = value;
+ }
+
+ /**
+ * This will get the dictionary associated with this field.
+ *
+ * @return The dictionary that this class wraps.
+ */
+ public COSDictionary getDictionary()
+ {
+ return dictionary;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return dictionary;
+ }
+
+ /**
+ * Get the additional actions for this field. This will return null
+ * if there are no additional actions for this field.
+ *
+ * @return The actions of the field.
+ */
+ public PDFormFieldAdditionalActions getActions()
+ {
+ COSDictionary aa = (COSDictionary)dictionary.getDictionaryObject( "AA" );
+ PDFormFieldAdditionalActions retval = null;
+ if( aa != null )
+ {
+ retval = new PDFormFieldAdditionalActions( aa );
+ }
+ return retval;
+ }
+
+ /**
+ * Set the actions of the field.
+ *
+ * @param actions The field actions.
+ */
+ public void setActions( PDFormFieldAdditionalActions actions )
+ {
+ dictionary.setItem( "AA", actions );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDFieldFactory.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDFieldFactory.java
new file mode 100644
index 0000000..c796714
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDFieldFactory.java
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2003-2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+
+import java.io.IOException;
+
+import java.util.List;
+
+/**
+ * This is the Factory for creating and returning the correct
+ * field elements.
+ *
+ * @author sug
+ * @version $Revision: 1.8 $
+ */
+public class PDFieldFactory
+{
+ private static final int RADIO_BITMASK = 32768;
+ private static final int PUSHBUTTON_BITMASK = 65536;
+ private static final int RADIOS_IN_UNISON_BITMASK = 33554432;
+
+ private static final String FIELD_TYPE_BTN = "Btn";
+ private static final String FIELD_TYPE_TX = "Tx";
+ private static final String FIELD_TYPE_CH = "Ch";
+ private static final String FIELD_TYPE_SIG = "Sig";
+
+ /**
+ * Utility class so no constructor.
+ */
+ private PDFieldFactory()
+ {
+ //do nothing.
+ }
+
+ /**
+ * This method creates a COSField subclass from the given field.
+ * The field is a PDF Dictionary object that must represent a
+ * field element. - othewise null is returned
+ *
+ * @param acroForm The form that the field will be part of.
+ * @param field The dictionary representing a field element
+ *
+ * @return a subclass to COSField according to the kind of field passed to createField
+ * @throws IOException If there is an error determining the field type.
+ */
+ public static PDField createField( PDAcroForm acroForm, COSDictionary field) throws IOException
+ {
+ PDField pdField = new PDUnknownField( acroForm, field );
+ if( isButton(pdField) )
+ {
+ int flags = pdField.getFieldFlags();
+ //BJL, I have found that the radio flag bit is not always set
+ //and that sometimes there is just a kids dictionary.
+ //so, if there is a kids dictionary then it must be a radio button
+ //group.
+ COSArray kids = (COSArray)field.getDictionaryObject( COSName.getPDFName( "Kids" ) );
+ if( kids != null || isRadio(flags) )
+ {
+ pdField = new PDRadioCollection( acroForm, field );
+ }
+ else if( isPushButton( flags ) )
+ {
+ pdField = new PDPushButton( acroForm, field );
+ }
+ else
+ {
+ pdField = new PDCheckbox( acroForm, field );
+ }
+
+ }
+ else if (isChoiceField(pdField))
+ {
+ pdField = new PDChoiceField( acroForm, field );
+ }
+ else if (isTextbox(pdField))
+ {
+ pdField = new PDTextbox( acroForm, field );
+ }
+ else if( isSignature( pdField ) )
+ {
+ pdField = new PDSignature( acroForm, field );
+ }
+ else
+ {
+ //do nothing and return an unknown field type.
+ }
+ return pdField;
+ }
+
+ /**
+ * This method determines if the given
+ * field is a radiobutton collection.
+ *
+ * @param flags The field flags.
+ *
+ * @return the result of the determination
+ */
+ private static boolean isRadio( int flags )
+ {
+ return (flags & RADIO_BITMASK) > 0;
+ }
+
+ /**
+ * This method determines if the given
+ * field is a pushbutton.
+ *
+ * @param flags The field flags.
+ *
+ * @return the result of the determination
+ */
+ private static boolean isPushButton( int flags )
+ {
+ return (flags & PUSHBUTTON_BITMASK) > 0;
+ }
+
+ /**
+ * This method determines if the given field is a choicefield
+ * Choicefields are either listboxes or comboboxes.
+ *
+ * @param field the field to determine
+ * @return the result of the determination
+ */
+ private static boolean isChoiceField(PDField field) throws IOException
+ {
+ return FIELD_TYPE_CH.equals(field.findFieldType());
+ }
+
+ /**
+ * This method determines if the given field is a button.
+ *
+ * @param field the field to determine
+ * @return the result of the determination
+ *
+ * @throws IOException If there is an error determining the field type.
+ */
+ private static boolean isButton(PDField field) throws IOException
+ {
+ String ft = field.findFieldType();
+ boolean retval = FIELD_TYPE_BTN.equals( ft );
+ List kids = field.getKids();
+ if( ft == null && kids != null && kids.size() > 0)
+ {
+ //sometimes if it is a button the type is only defined by one
+ //of the kids entries
+ Object obj = kids.get( 0 );
+ COSDictionary kidDict = null;
+ if( obj instanceof PDField )
+ {
+ kidDict = ((PDField)obj).getDictionary();
+ }
+ else if( obj instanceof PDAnnotationWidget )
+ {
+ kidDict = ((PDAnnotationWidget)obj).getDictionary();
+ }
+ else
+ {
+ throw new IOException( "Error:Unexpected type of kids field:" + obj );
+ }
+ retval = isButton( new PDUnknownField( field.getAcroForm(), kidDict ) );
+ }
+ return retval;
+ }
+
+ /**
+ * This method determines if the given field is a signature.
+ *
+ * @param field the field to determine
+ * @return the result of the determination
+ */
+ private static boolean isSignature(PDField field) throws IOException
+ {
+ return FIELD_TYPE_SIG.equals(field.findFieldType());
+ }
+
+ /**
+ * This method determines if the given field is a Textbox.
+ *
+ * @param field the field to determine
+ * @return the result of the determination
+ */
+ private static boolean isTextbox(PDField field) throws IOException
+ {
+ return FIELD_TYPE_TX.equals(field.findFieldType());
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDPushButton.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDPushButton.java
new file mode 100644
index 0000000..e832921
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDPushButton.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSString;
+
+import java.io.IOException;
+
+/**
+ * A class for handling the PDF field as a PDPushButton.
+ *
+ * @author sug
+ * @version $Revision: 1.3 $
+ */
+public class PDPushButton extends PDField
+{
+
+ /**
+ * @see org.pdfbox.pdmodel.field.PDField#COSField(org.pdfbox.cos.COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field for this push button.
+ */
+ public PDPushButton( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super(theAcroForm, field);
+ }
+
+ /**
+ * @see as.interactive.pdf.form.cos.COSField#setValue(java.lang.String)
+ *
+ * @param value The new value for the field.
+ *
+ * @throws IOException If there is an error creating the appearance stream.
+ */
+ public void setValue(String value) throws IOException
+ {
+ COSString fieldValue = new COSString(value);
+ getDictionary().setItem( COSName.getPDFName( "V" ), fieldValue );
+ getDictionary().setItem( COSName.getPDFName( "DV" ), fieldValue );
+ }
+
+ /**
+ * getValue gets the fields value to as a string.
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error getting the value.
+ */
+ public String getValue() throws IOException
+ {
+ return getDictionary().getString( "V" );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDRadioCollection.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDRadioCollection.java
new file mode 100644
index 0000000..27b48d6
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDRadioCollection.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2003-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.pdmodel.common.COSArrayList;
+import org.pdfbox.util.BitFlagHelper;
+
+/**
+ * A class for handling the PDF field as a Radio Collection.
+ * This class automatically keeps track of the child radio buttons
+ * in the collection.
+ *
+ * @see PDCheckbox
+ * @author sug
+ * @version $Revision: 1.12 $
+ */
+public class PDRadioCollection extends PDChoiceButton
+{
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_RADIOS_IN_UNISON = 1 << 25;
+
+ /**
+ * @see PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field that makes up the radio collection.
+ */
+ public PDRadioCollection( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super(theAcroForm,field);
+ }
+
+ /**
+ * From the PDF Spec <br/>
+ * If set, a group of radio buttons within a radio button field that
+ * use the same value for the on state will turn on and off in unison; that is if
+ * one is checked, they are all checked. If clear, the buttons are mutually exclusive
+ * (the same behavior as HTML radio buttons).
+ *
+ * @param radiosInUnison The new flag for radiosInUnison.
+ */
+ public void setRadiosInUnison(boolean radiosInUnison)
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_RADIOS_IN_UNISON, radiosInUnison );
+ }
+
+ /**
+ *
+ * @return true If the flag is set for radios in unison.
+ */
+ public boolean isRadiosInUnison()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_RADIOS_IN_UNISON );
+ }
+
+ /**
+ * This setValue method iterates the collection of radiobuttons
+ * and checks or unchecks each radiobutton according to the
+ * given value.
+ * If the value is not represented by any of the radiobuttons,
+ * then none will be checked.
+ *
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#setValue(java.lang.String)
+ */
+ public void setValue(String value) throws IOException
+ {
+ getDictionary().setString( "V", value );
+ List kids = getKids();
+ for (int i = 0; i < kids.size(); i++)
+ {
+ PDCheckbox btn = (PDCheckbox)kids.get(i);
+ if( btn.getOnValue().equals(value) )
+ {
+ btn.check();
+ }
+ else
+ {
+ btn.unCheck();
+ }
+ }
+ }
+
+ /**
+ * getValue gets the fields value to as a string.
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error getting the value.
+ */
+ public String getValue()throws IOException
+ {
+ String retval = null;
+ List kids = getKids();
+ for (int i = 0; i < kids.size(); i++)
+ {
+ PDCheckbox btn = (PDCheckbox)kids.get(i);
+ if( btn.isChecked() )
+ {
+ retval = btn.getOnValue();
+ }
+ }
+ if( retval == null )
+ {
+ retval = getDictionary().getNameAsString( "V" );
+ }
+ return retval;
+ }
+
+
+ /**
+ * This will return a list of PDField objects that are part of this radio collection.
+ *
+ * @see PDField#getWidget()
+ * @return A list of PDWidget objects.
+ * @throws IOException if there is an error while creating the children objects.
+ */
+ public List getKids() throws IOException
+ {
+ List retval = null;
+ COSArray kids = (COSArray)getDictionary().getDictionaryObject(COSName.KIDS);
+ if( kids != null )
+ {
+ List kidsList = new ArrayList();
+ for (int i = 0; i < kids.size(); i++)
+ {
+ kidsList.add( PDFieldFactory.createField( getAcroForm(), (COSDictionary)kids.getObject(i) ) );
+ }
+ retval = new COSArrayList( kidsList, kids );
+ }
+ return retval;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDSignature.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDSignature.java
new file mode 100644
index 0000000..66ed3e3
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDSignature.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSDictionary;
+
+import java.io.IOException;
+
+/**
+ * A class for handling the PDF field as a signature.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDSignature extends PDField
+{
+
+ /**
+ * @see org.pdfbox.pdmodel.field.PDField#COSField(org.pdfbox.cos.COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The dictionary for the signature.
+ */
+ public PDSignature( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super(theAcroForm,field);
+ }
+
+ /**
+ * @see as.interactive.pdf.form.cos.COSField#setValue(java.lang.String)
+ *
+ * @param value The new value for the field.
+ *
+ * @throws IOException If there is an error creating the appearance stream.
+ */
+ public void setValue(String value) throws IOException
+ {
+ throw new RuntimeException( "Not yet implemented" );
+ }
+
+ /**
+ * @see as.interactive.pdf.form.cos.COSField#setValue(java.lang.String)
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error creating the appearance stream.
+ */
+ public String getValue() throws IOException
+ {
+ throw new RuntimeException( "Not yet implemented" );
+ }
+
+ /**
+ * Return a string rep of this object.
+ *
+ * @return A string rep of this object.
+ */
+ public String toString()
+ {
+ return "PDSignature";
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDTextbox.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDTextbox.java
new file mode 100644
index 0000000..fd9550e
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDTextbox.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSDictionary;
+
+/**
+ * A class for handling the PDF field as a textbox.
+ *
+ * @author sug
+ * @version $Revision: 1.9 $
+ */
+public class PDTextbox extends PDVariableText
+{
+
+ /**
+ * @see PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroform.
+ */
+ public PDTextbox( PDAcroForm theAcroForm )
+ {
+ super( theAcroForm );
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field's dictionary.
+ */
+ public PDTextbox( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super( theAcroForm, field);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDUnknownField.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDUnknownField.java
new file mode 100644
index 0000000..806b5f5
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDUnknownField.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2003, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSDictionary;
+
+/**
+ * This class represents a form field with an unknown type.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDUnknownField extends PDField
+{
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#PDField(PDAcroForm, COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field's dictionary.
+ */
+ public PDUnknownField( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super( theAcroForm, field);
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#setValue(String)
+ */
+ public void setValue(String value) throws IOException
+ {
+ //do nothing
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#getValue()
+ */
+ public String getValue() throws IOException
+ {
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/PDVariableText.java b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDVariableText.java
new file mode 100644
index 0000000..7ed5008
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/PDVariableText.java
@@ -0,0 +1,324 @@
+/**
+ * Copyright (c) 2004-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.form;
+
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSInteger;
+import org.pdfbox.cos.COSName;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.cos.COSString;
+import org.pdfbox.util.BitFlagHelper;
+
+import java.io.IOException;
+
+/**
+ * A class for handling PDF fields that display text.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.6 $
+ */
+public abstract class PDVariableText extends PDField
+{
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_MULTILINE = 1 << 12;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_PASSWORD = 1 << 13;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_FILE_SELECT = 1 << 20;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_DO_NOT_SPELL_CHECK = 1 << 22;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_DO_NOT_SCROLL = 1 << 23;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_COMB = 1 << 24;
+ /**
+ * A Ff flag.
+ */
+ public static final int FLAG_RICH_TEXT = 1 << 25;
+
+
+ /**
+ * DA Default appearance.
+ */
+ private COSString da;
+
+ private PDAppearance appearance;
+
+
+ /**
+ * A Q value.
+ */
+ public static final int QUADDING_LEFT = 0;
+
+ /**
+ * A Q value.
+ */
+ public static final int QUADDING_CENTERED = 1;
+
+ /**
+ * A Q value.
+ */
+ public static final int QUADDING_RIGHT = 2;
+
+ /**
+ * @see PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroform.
+ */
+ public PDVariableText( PDAcroForm theAcroForm )
+ {
+ super( theAcroForm );
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#PDField(PDAcroForm,COSDictionary)
+ *
+ * @param theAcroForm The acroForm for this field.
+ * @param field The field's dictionary.
+ */
+ public PDVariableText( PDAcroForm theAcroForm, COSDictionary field)
+ {
+ super( theAcroForm, field);
+ da = (COSString) field.getDictionaryObject(COSName.getPDFName("DA"));
+ }
+
+ /**
+ * @see org.pdfbox.pdmodel.interactive.form.PDField#setValue(java.lang.String)
+ *
+ * @param value The new value for this text field.
+ *
+ * @throws IOException If there is an error calculating the appearance stream.
+ */
+ public void setValue(String value) throws IOException
+ {
+ COSString fieldValue = new COSString(value);
+ getDictionary().setItem( COSName.getPDFName( "V" ), fieldValue );
+
+ //hmm, not sure what the case where the DV gets set to the field
+ //value, for now leave blank until we can come up with a case
+ //where it needs to be in there
+ //getDictionary().setItem( COSName.getPDFName( "DV" ), fieldValue );
+ if(appearance == null)
+ {
+ this.appearance = new PDAppearance( getAcroForm(), this );
+ }
+ appearance.setAppearanceValue(value);
+ }
+
+ /**
+ * getValue gets the fields value to as a string.
+ *
+ * @return The string value of this field.
+ *
+ * @throws IOException If there is an error getting the value.
+ */
+ public String getValue() throws IOException
+ {
+ return getDictionary().getString( "V" );
+ }
+
+ /**
+ * @return true if the field is multiline
+ */
+ public boolean isMultiline()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_MULTILINE );
+ }
+
+ /**
+ * Set the multiline bit.
+ *
+ * @param multiline The value for the multiline.
+ */
+ public void setMultiline( boolean multiline )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_MULTILINE, multiline );
+ }
+
+ /**
+ * @return true if the field is a password field.
+ */
+ public boolean isPassword()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_PASSWORD );
+ }
+
+ /**
+ * Set the password bit.
+ *
+ * @param password The value for the password.
+ */
+ public void setPassword( boolean password )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_PASSWORD, password );
+ }
+
+ /**
+ * @return true if the field is a file select field.
+ */
+ public boolean isFileSelect()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_FILE_SELECT );
+ }
+
+ /**
+ * Set the file select bit.
+ *
+ * @param fileSelect The value for the fileSelect.
+ */
+ public void setFileSelect( boolean fileSelect )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_FILE_SELECT, fileSelect );
+ }
+
+ /**
+ * @return true if the field is not suppose to spell check.
+ */
+ public boolean doNotSpellCheck()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_DO_NOT_SPELL_CHECK );
+ }
+
+ /**
+ * Set the doNotSpellCheck bit.
+ *
+ * @param doNotSpellCheck The value for the doNotSpellCheck.
+ */
+ public void setDoNotSpellCheck( boolean doNotSpellCheck )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_DO_NOT_SPELL_CHECK, doNotSpellCheck );
+ }
+
+ /**
+ * @return true if the field is not suppose to scroll.
+ */
+ public boolean doNotScroll()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_DO_NOT_SCROLL );
+ }
+
+ /**
+ * Set the doNotScroll bit.
+ *
+ * @param doNotScroll The value for the doNotScroll.
+ */
+ public void setDoNotScroll( boolean doNotScroll )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_DO_NOT_SCROLL, doNotScroll );
+ }
+
+ /**
+ * @return true if the field is not suppose to comb the text display.
+ */
+ public boolean shouldComb()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_COMB );
+ }
+
+ /**
+ * Set the comb bit.
+ *
+ * @param comb The value for the comb.
+ */
+ public void setComb( boolean comb )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_COMB, comb );
+ }
+
+ /**
+ * @return true if the field is a rich text field.
+ */
+ public boolean isRichText()
+ {
+ return BitFlagHelper.getFlag( getDictionary(), "Ff", FLAG_RICH_TEXT );
+ }
+
+ /**
+ * Set the richText bit.
+ *
+ * @param richText The value for the richText.
+ */
+ public void setRichText( boolean richText )
+ {
+ BitFlagHelper.setFlag( getDictionary(), "Ff", FLAG_RICH_TEXT, richText );
+ }
+
+ /**
+ * @return the DA element of the dictionary object
+ */
+ protected COSString getDefaultAppearance()
+ {
+ return da;
+ }
+
+ /**
+ * This will get the 'quadding' or justification of the text to be displayed.
+ * 0 - Left(default)<br/>
+ * 1 - Centered<br />
+ * 2 - Right<br />
+ * Please see the QUADDING_CONSTANTS.
+ *
+ * @return The justification of the text strings.
+ */
+ public int getQ()
+ {
+ int retval = 0;
+ COSNumber number = (COSNumber)getDictionary().getDictionaryObject( COSName.getPDFName( "Q" ) );
+ if( number != null )
+ {
+ retval = number.intValue();
+ }
+ return retval;
+ }
+
+ /**
+ * This will set the quadding/justification of the text. See QUADDING constants.
+ *
+ * @param q The new text justification.
+ */
+ public void setQ( int q )
+ {
+ getDictionary().setItem( COSName.getPDFName( "Q" ), new COSInteger( q ) );
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/form/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/form/package.html
new file mode 100644
index 0000000..36c4b4b
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/form/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+The interactive package contains classes that deal with interactive annotations such as textfields and buttons.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThread.java b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThread.java
new file mode 100644
index 0000000..5226099
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThread.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.pagenavigation;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.PDDocumentInformation;
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * This a single thread in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PDThread implements COSObjectable
+{
+
+
+ private COSDictionary thread;
+
+ /**
+ * Constructor that is used for a preexisting dictionary.
+ *
+ * @param t The underlying dictionary.
+ */
+ public PDThread( COSDictionary t )
+ {
+ thread = t;
+ }
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDThread()
+ {
+ thread = new COSDictionary();
+ thread.setName( "Type", "Thread" );
+ }
+
+ /**
+ * This will get the underlying dictionary that this object wraps.
+ *
+ * @return The underlying info dictionary.
+ */
+ public COSDictionary getDictionary()
+ {
+ return thread;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return thread;
+ }
+
+ /**
+ * Get info about the thread, or null if there is nothing.
+ *
+ * @return The thread information.
+ */
+ public PDDocumentInformation getThreadInfo()
+ {
+ PDDocumentInformation retval = null;
+ COSDictionary info = (COSDictionary)thread.getDictionaryObject( "I" );
+ if( info != null )
+ {
+ retval = new PDDocumentInformation( info );
+ }
+
+ return retval;
+ }
+
+ /**
+ * Set the thread info, can be null.
+ *
+ * @param info The info dictionary about this thread.
+ */
+ public void setThreadInfo( PDDocumentInformation info )
+ {
+ thread.setItem( "I", info );
+ }
+
+ /**
+ * Get the first bead in the thread, or null if it has not been set yet. This
+ * is a required field for this object.
+ *
+ * @return The first bead in the thread.
+ */
+ public PDThreadBead getFirstBead()
+ {
+ PDThreadBead retval = null;
+ COSDictionary bead = (COSDictionary)thread.getDictionaryObject( "F" );
+ if( bead != null )
+ {
+ retval = new PDThreadBead( bead );
+ }
+
+ return retval;
+ }
+
+ /**
+ * This will set the first bead in the thread. When this is set it will
+ * also set the thread property of the bead object.
+ *
+ * @param bead The first bead in the thread.
+ */
+ public void setFirstBead( PDThreadBead bead )
+ {
+ if( bead != null )
+ {
+ bead.setThread( this );
+ }
+ thread.setItem( "F", bead );
+ }
+
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThreadBead.java b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThreadBead.java
new file mode 100644
index 0000000..547d4bc
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/PDThreadBead.java
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.pagenavigation;
+
+import org.pdfbox.cos.COSArray;
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.pdmodel.PDPage;
+import org.pdfbox.pdmodel.common.COSObjectable;
+import org.pdfbox.pdmodel.common.PDRectangle;
+
+/**
+ * This a single bead in a thread in a PDF document.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class PDThreadBead implements COSObjectable
+{
+
+
+ private COSDictionary bead;
+
+ /**
+ * Constructor that is used for a preexisting dictionary.
+ *
+ * @param b The underlying dictionary.
+ */
+ public PDThreadBead( COSDictionary b )
+ {
+ bead = b;
+ }
+
+ /**
+ * Default constructor.
+ *
+ */
+ public PDThreadBead()
+ {
+ bead = new COSDictionary();
+ bead.setName( "Type", "Bead" );
+ setNextBead( this );
+ setPreviousBead( this );
+ }
+
+ /**
+ * This will get the underlying dictionary that this object wraps.
+ *
+ * @return The underlying info dictionary.
+ */
+ public COSDictionary getDictionary()
+ {
+ return bead;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return bead;
+ }
+
+ /**
+ * This will get the thread that this bead is part of. This is only required
+ * for the first bead in a thread, so other beads 'may' return null.
+ *
+ * @return The thread that this bead is part of.
+ */
+ public PDThread getThread()
+ {
+ PDThread retval = null;
+ COSDictionary dic = (COSDictionary)bead.getDictionaryObject( "T" );
+ if( dic != null )
+ {
+ retval = new PDThread( dic );
+ }
+ return retval;
+ }
+
+ /**
+ * Set the thread that this bead is part of. This is only required for the
+ * first bead in a thread. Note: This property is set for you by the PDThread.setFirstBead() method.
+ *
+ * @param thread The thread that this bead is part of.
+ */
+ public void setThread( PDThread thread )
+ {
+ bead.setItem( "T", thread );
+ }
+
+ /**
+ * This will get the next bead. If this bead is the last bead in the list then this
+ * will return the first bead.
+ *
+ * @return The next bead in the list or the first bead if this is the last bead.
+ */
+ public PDThreadBead getNextBead()
+ {
+ return new PDThreadBead( (COSDictionary) bead.getDictionaryObject( "N" ) );
+ }
+
+ /**
+ * Set the next bead in the thread.
+ *
+ * @param next The next bead.
+ */
+ protected void setNextBead( PDThreadBead next )
+ {
+ bead.setItem( "N", next );
+ }
+
+ /**
+ * This will get the previous bead. If this bead is the first bead in the list then this
+ * will return the last bead.
+ *
+ * @return The previous bead in the list or the last bead if this is the first bead.
+ */
+ public PDThreadBead getPreviousBead()
+ {
+ return new PDThreadBead( (COSDictionary) bead.getDictionaryObject( "V" ) );
+ }
+
+ /**
+ * Set the previous bead in the thread.
+ *
+ * @param previous The previous bead.
+ */
+ protected void setPreviousBead( PDThreadBead previous )
+ {
+ bead.setItem( "V", previous );
+ }
+
+ /**
+ * Append a bead after this bead. This will correctly set the next/previous beads in the
+ * linked list.
+ *
+ * @param append The bead to insert.
+ */
+ public void appendBead( PDThreadBead append )
+ {
+ PDThreadBead nextBead = getNextBead();
+ nextBead.setPreviousBead( append );
+ append.setNextBead( nextBead );
+ setNextBead( append );
+ append.setPreviousBead( this );
+ }
+
+ /**
+ * Get the page that this bead is part of.
+ *
+ * @return The page that this bead is part of.
+ */
+ public PDPage getPage()
+ {
+ PDPage page = null;
+ COSDictionary dic = (COSDictionary)bead.getDictionaryObject( "P" );
+ if( dic != null )
+ {
+ page = new PDPage( dic );
+ }
+ return page;
+ }
+
+ /**
+ * Set the page that this bead is part of. This is a required property and must be
+ * set when creating a new bead. The PDPage object also has a list of beads in the natural
+ * reading order. It is recommended that you add this object to that list as well.
+ *
+ * @param page The page that this bead is on.
+ */
+ public void setPage( PDPage page )
+ {
+ bead.setItem( "P", page );
+ }
+
+ /**
+ * The rectangle on the page that this bead is part of.
+ *
+ * @return The part of the page that this bead covers.
+ */
+ public PDRectangle getRectangle()
+ {
+ PDRectangle rect = null;
+ COSArray array = (COSArray)bead.getDictionaryObject( COSName.R );
+ if( array != null )
+ {
+ rect = new PDRectangle( array );
+ }
+ return rect;
+ }
+
+ /**
+ * Set the rectangle on the page that this bead covers.
+ *
+ * @param rect The portion of the page that this bead covers.
+ */
+ public void setRectangle( PDRectangle rect )
+ {
+ bead.setItem( COSName.R, rect );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/package.html
new file mode 100644
index 0000000..5fb1b88
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/pagenavigation/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+A package to allow provide access to PDF page navigation functionality.
+</body>
+</html>
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/PDViewerPreferences.java b/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/PDViewerPreferences.java
new file mode 100644
index 0000000..d9958e6
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/PDViewerPreferences.java
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2003-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.pdmodel.interactive.viewerpreferences;
+
+import org.pdfbox.cos.COSBase;
+import org.pdfbox.cos.COSDictionary;
+
+import org.pdfbox.pdmodel.common.COSObjectable;
+
+/**
+ * This is the document viewing preferences.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.2 $
+ */
+public class PDViewerPreferences implements COSObjectable
+{
+ /**
+ * From PDF Reference: "Neither document outline nor thumbnail images visible".
+ */
+ public static final String NON_FULL_SCREEN_PAGE_MODE_USE_NONE = "UseNone";
+ /**
+ * From PDF Reference: "Document outline visible".
+ */
+ public static final String NON_FULL_SCREEN_PAGE_MODE_USE_OUTLINES = "UseOutlines";
+ /**
+ * From PDF Reference: "Thumbnail images visible".
+ */
+ public static final String NON_FULL_SCREEN_PAGE_MODE_USE_THUMBS = "UseThumbs";
+ /**
+ * From PDF Reference: "Optional content group panel visible".
+ */
+ public static final String NON_FULL_SCREEN_PAGE_MODE_USE_OPTIONAL_CONTENT = "UseOC";
+
+ /**
+ * Reading direction.
+ */
+ public static final String READING_DIRECTION_L2R = "L2R";
+ /**
+ * Reading direction.
+ */
+ public static final String READING_DIRECTION_R2L = "R2L";
+
+ /**
+ * Boundary constant.
+ */
+ public static final String BOUNDARY_MEDIA_BOX = "MediaBox";
+ /**
+ * Boundary constant.
+ */
+ public static final String BOUNDARY_CROP_BOX = "CropBox";
+ /**
+ * Boundary constant.
+ */
+ public static final String BOUNDARY_BLEED_BOX = "BleedBox";
+ /**
+ * Boundary constant.
+ */
+ public static final String BOUNDARY_TRIM_BOX = "TrimBox";
+ /**
+ * Boundary constant.
+ */
+ public static final String BOUNDARY_ART_BOX = "ArtBox";
+
+
+ private COSDictionary prefs;
+
+ /**
+ * Constructor that is used for a preexisting dictionary.
+ *
+ * @param dic The underlying dictionary.
+ */
+ public PDViewerPreferences( COSDictionary dic )
+ {
+ prefs = dic;
+ }
+
+ /**
+ * This will get the underlying dictionary that this object wraps.
+ *
+ * @return The underlying info dictionary.
+ */
+ public COSDictionary getDictionary()
+ {
+ return prefs;
+ }
+
+ /**
+ * Convert this standard java object to a COS object.
+ *
+ * @return The cos object that matches this Java object.
+ */
+ public COSBase getCOSObject()
+ {
+ return prefs;
+ }
+
+ /**
+ * Get the toolbar preference.
+ *
+ * @return the toolbar preference.
+ */
+ public boolean hideToolbar()
+ {
+ return prefs.getBoolean( "HideToolbar", false );
+ }
+
+ /**
+ * Set the toolbar preference.
+ *
+ * @param value Set the toolbar preference.
+ */
+ public void setHideToolbar( boolean value )
+ {
+ prefs.setBoolean( "HideToolbar", value );
+ }
+
+ /**
+ * Get the menubar preference.
+ *
+ * @return the menubar preference.
+ */
+ public boolean hideMenubar()
+ {
+ return prefs.getBoolean( "HideMenubar", false );
+ }
+
+ /**
+ * Set the menubar preference.
+ *
+ * @param value Set the menubar preference.
+ */
+ public void setHideMenubar( boolean value )
+ {
+ prefs.setBoolean( "HideMenubar", value );
+ }
+
+ /**
+ * Get the window UI preference.
+ *
+ * @return the window UI preference.
+ */
+ public boolean hideWindowUI()
+ {
+ return prefs.getBoolean( "HideWindowUI", false );
+ }
+
+ /**
+ * Set the window UI preference.
+ *
+ * @param value Set the window UI preference.
+ */
+ public void setHideWindowUI( boolean value )
+ {
+ prefs.setBoolean( "HideWindowUI", value );
+ }
+
+ /**
+ * Get the fit window preference.
+ *
+ * @return the fit window preference.
+ */
+ public boolean fitWindow()
+ {
+ return prefs.getBoolean( "FitWindow", false );
+ }
+
+ /**
+ * Set the fit window preference.
+ *
+ * @param value Set the fit window preference.
+ */
+ public void setFitWindow( boolean value )
+ {
+ prefs.setBoolean( "FitWindow", value );
+ }
+
+ /**
+ * Get the center window preference.
+ *
+ * @return the center window preference.
+ */
+ public boolean centerWindow()
+ {
+ return prefs.getBoolean( "CenterWindow", false );
+ }
+
+ /**
+ * Set the center window preference.
+ *
+ * @param value Set the center window preference.
+ */
+ public void setCenterWindow( boolean value )
+ {
+ prefs.setBoolean( "CenterWindow", value );
+ }
+
+ /**
+ * Get the display doc title preference.
+ *
+ * @return the display doc title preference.
+ */
+ public boolean displayDocTitle()
+ {
+ return prefs.getBoolean( "DisplayDocTitle", false );
+ }
+
+ /**
+ * Set the display doc title preference.
+ *
+ * @param value Set the display doc title preference.
+ */
+ public void setDisplayDocTitle( boolean value )
+ {
+ prefs.setBoolean( "DisplayDocTitle", value );
+ }
+
+ /**
+ * Get the non full screen page mode preference.
+ *
+ * @return the non full screen page mode preference.
+ */
+ public String getNonFullScreenPageMode()
+ {
+ return prefs.getNameAsString( "NonFullScreenPageMode", NON_FULL_SCREEN_PAGE_MODE_USE_NONE);
+ }
+
+ /**
+ * Set the non full screen page mode preference.
+ *
+ * @param value Set the non full screen page mode preference.
+ */
+ public void setNonFullScreenPageMode( String value )
+ {
+ prefs.setName( "NonFullScreenPageMode", value );
+ }
+
+ /**
+ * Get the reading direction preference.
+ *
+ * @return the reading direction preference.
+ */
+ public String getReadingDirection()
+ {
+ return prefs.getNameAsString( "Direction", READING_DIRECTION_L2R);
+ }
+
+ /**
+ * Set the reading direction preference.
+ *
+ * @param value Set the reading direction preference.
+ */
+ public void setReadingDirection( String value )
+ {
+ prefs.setName( "Direction", value );
+ }
+
+ /**
+ * Get the ViewArea preference. See BOUNDARY_XXX constants.
+ *
+ * @return the ViewArea preference.
+ */
+ public String getViewArea()
+ {
+ return prefs.getNameAsString( "ViewArea", BOUNDARY_CROP_BOX);
+ }
+
+ /**
+ * Set the ViewArea preference. See BOUNDARY_XXX constants.
+ *
+ * @param value Set the ViewArea preference.
+ */
+ public void setViewArea( String value )
+ {
+ prefs.setName( "ViewArea", value );
+ }
+
+ /**
+ * Get the ViewClip preference. See BOUNDARY_XXX constants.
+ *
+ * @return the ViewClip preference.
+ */
+ public String getViewClip()
+ {
+ return prefs.getNameAsString( "ViewClip", BOUNDARY_CROP_BOX);
+ }
+
+ /**
+ * Set the ViewClip preference. See BOUNDARY_XXX constants.
+ *
+ * @param value Set the ViewClip preference.
+ */
+ public void setViewClip( String value )
+ {
+ prefs.setName( "ViewClip", value );
+ }
+
+ /**
+ * Get the PrintArea preference. See BOUNDARY_XXX constants.
+ *
+ * @return the PrintArea preference.
+ */
+ public String getPrintArea()
+ {
+ return prefs.getNameAsString( "PrintArea", BOUNDARY_CROP_BOX);
+ }
+
+ /**
+ * Set the PrintArea preference. See BOUNDARY_XXX constants.
+ *
+ * @param value Set the PrintArea preference.
+ */
+ public void setPrintArea( String value )
+ {
+ prefs.setName( "PrintArea", value );
+ }
+
+ /**
+ * Get the PrintClip preference. See BOUNDARY_XXX constants.
+ *
+ * @return the PrintClip preference.
+ */
+ public String getPrintClip()
+ {
+ return prefs.getNameAsString( "PrintClip", BOUNDARY_CROP_BOX);
+ }
+
+ /**
+ * Set the PrintClip preference. See BOUNDARY_XXX constants.
+ *
+ * @param value Set the PrintClip preference.
+ */
+ public void setPrintClip( String value )
+ {
+ prefs.setName( "PrintClip", value );
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/package.html b/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/package.html
new file mode 100644
index 0000000..310d6b4
--- /dev/null
+++ b/src/main/java/org/pdfbox/pdmodel/interactive/viewerpreferences/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+A package to allow access to document viewing preferences.
+</body>
+</html>